25 พฤศจิกายน 2556

[Android Code] การสร้าง Animation จาก Animation Resource [Anim]


        ประกาศ - บทความนี้เก่าแล้วนะครับ แนะนำให้ใช้ ObjectAnimator จากบทความนี้แทนครับ ^^ [Android Code] มาทำความรู้จักกับ Object Animator กันดีกว่า~!

        สำหรับบทความเกี่ยวกับ Animation เจ้าของบล็อกเคยพูดถึงไปแล้ว แต่เป็นการทำ Animation แบบง่ายๆที่ต้องใช้โค๊ดในการกำหนด ดังนั้นอาจจะเกิดการใช้งานจริงแล้วโค๊ดมันเยอะและดูวุ่นวาย ก็เลยนำเสนออีกวิธีหนึ่งในการกำหนด Animation โดยลดโค๊ดลง นั่นก็คือการสร้าง Resource สำหรับ Animation เพื่อเรียกใช้งานเลย

        ก่อนอื่น จะต้องสร้างโฟลเดอร์ชื่อ anim ไว้ใน res ก่อนนะ เพราะตอนสร้างโปรเจคขึ้นมามันจะยังไม่มีให้ ต้องสร้างเอง



        จากนั้นก็สร้างไฟล์ XML สำหรับ Animation เลย




        ทีนี้ก็ตั้งชื่อไฟล์ Resource ที่จะสร้างได้ตามใจชอบเลย และจะเห็นว่ามีให้เลือก Alpha, Rotate, Scale, Set และ Translate ซึ่ง Alpha, Rotate, Scale, Translate ก็รู้กันอยู่แล้วว่าอันไหนเป็นยังไง แต่สำหรับ Set ก็คือเป็นการรวมรูปแบบ Animation เข้าด้วยกัน อย่างเช่นใช้ Scale กับ Alpha เพื่อให้ Button ขยายแล้วจางหายไป ซึ่งก็คือการเอาโค๊ดของแต่ละอันไปใส่ไว้ใน Set นั่นเอง ดังนั้นเจ้าของบล็อกจึงขอใช้เป็น Set ไปเลยน่าจะง่ายดี



        เมื่อสร้างขึ้นมาแล้วก็จะพบกับโค๊ดเริ่มต้นดังนี้



        ภายใน Tag ของ Set สามารถกำหนด Animation ต่างๆได้เลย ให้เคอร์เซอร์อยู่ภายใน Tag ของ Set แล้วกด Ctrl + Enter ดู ก็จะเห็นว่ามี Animation ให้เลือกกำหนดลงไปได้




        สมมติว่าเจ้าของบล็อกเลือกเป็น Alpha ละกันนะ



        พอลองกด Ctrl + Enter ดูก็จะเห็น Attribute ต่างๆให้เลือกกำหนด ซึ่งเดากันได้ไม่ยากหรอก ถ้าเคยทำ Alpha แบบโค๊ด Java กันมาแล้ว



        ทีนี้เจ้าของบล็อกลองกำหนดค่าดังนี้ดู

my_anim.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    
    <alpha android:fromAlpha="0"
        android:toAlpha="1" 
        android:duration="1000" />

</set>

        fromAlpha ก็คือความโปร่งตอนที่เริ่มต้น กำหนดไว้เป็น 0 คือ 0% และ toAlpha ก็คือความโปร่งที่ตอนจบ กำหนดไว้เป็น 1 คือ 100% เนื่องจากทั้งสองอันนี้กำหนดค่าเป็น Float มีค่าระหว่าง 0 - 1 เพราะงั้นถ้าต้องการที่ 50% ก็ให้กำหนดค่าเป็น 0.5 โดย Alpha จาก 0 ไป 1 จะใช้เวลาทั้งหมด 1 วินาที ตามที่กำหนดไว้ใน Duration ที่มีหน่วยเป็นมิลลิวินาที

        ทีนี้ข้ามมาดูการเรียกใช้งานใน Java กันเลย ก่อนอื่นต้องกำหนด Layout ที่จะแสดงตัวอย่างก่อน ก็ไม่อยากให้วุ่นวายนัก ลองใช้กับ Text View นั่นแหละ (จำไว้ว่า Animtation แบบนี้สามารถใช้กับ View ใน Layout ได้ทุกตัว) โดยลาก Text View ไว้ตรงกลางจอหน่อย แล้วจะใช้ Animation จาก Resource ที่ได้สร้างขึ้นมา มากำหนดให้กับ Text View โดยกำหนดให้ Text View มี ID เป็น textView

main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="@string/hello_world" />

</RelativeLayout>


        มาดูกันต่อที่โค๊ด Java

Main.java
package app.akexorcist.animationresource;

import android.os.Bundle;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.TextView;
import android.app.Activity;

public class Main extends Activity {

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        Animation anim = AnimationUtils.loadAnimation(this, R.anim.my_anim);
        
        TextView textView = (TextView)findViewById(R.id.textView);
        textView.setAnimation(anim);
        
    }
}

        สั้นมั้ยล่ะ!! หัวใจสำคัญอยู่ที่คลาส Animation ที่กำหนดค่าจาก Resource ที่สร้างไว้นั่นเอง แล้วนำไปกำหนดในคำสั่ง setAnimation ได้เลย

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="app.akexorcist.animationresource"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="19" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="app.akexorcist.animationresource.Main"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

        บางทีแอปพลิเคชันดันเล่น Animation จบก่อน Layout แสดง ดังนั้นอาจจะมองไม่เห็นว่า Animation มันทำงาน เพราะเจ้าของบล็อกสั่งให้ Animation ทำงานทันทีใน onCreate ให้ลองหมุนหน้าจอเพื่อให้มันทำงานใหม่อีกครั้งก็ได้ จะได้เห็น

        แต่บทความยังไม่จบแต่เพียงเท่านี้นหรอกนะ จะพูดเรื่องการสร้าง Animation ในแบบอื่นๆกันต่อ สมมติว่าสร้าง Animation เป็น Rotate ละกันนะ

my_anim_2.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillEnabled="false"
    android:fillBefore="false" 
    android:fillAfter="true" >
    
    <rotate android:fromDegrees="0"
        android:toDegrees="180"
        android:pivotX="50%"
        android:pivotY="50%"
        android:duration="500" />

</set>
        ในตัวอย่างนี้จะให้ Text View หมุนจาก 0 องศาไปยัง 180 องศา แล้วจุดหมุน (Pivot) อยู่ที่กึ่งกลางของ Text View ทั้งแกน X และ Y โดยมีระยะเวลาในการหมุนอยู่ที่ 500 มิลลิวินาทีหรือ 5 วินาที เจ้าของบล็อกขอเพิ่มคำสั่ง Fill เข้าไปหน่อย เป็นตัวอย่าง ปกติการแสดง Animation เมื่อจบแล้ว วัตถุจะกลับไปเป็นสภาพเดิม แต่ในทีนี้เจ้าของบล็อกให้หมุน 180 องศา ก็คือกลับหัวนั่นเอง ถ้าไม่ใช่ Fill ตอนทำงาน Text View ก็จะหมุนไปเรื่อยๆจนกลับหัว แต่พอหมุนเสร็จแล้วก็จะกลับมาสภาพเดิม คือไม่กลับหัว ถ้าอยากให้คงสถานะสุดท้ายไว้ก็ต้องใช้คำสั่งของ Fill เข้ามาช่วย โดยกำหนดให้ filleEnable กับ fillBefore เป็น False ส่วน fillAfter เป็น True ก็จะทำให้วัตถุหมุนกลับหัวแล้วหยุดค้างสถานะอยู่แบบนั้นเลย

        แล้วถ้าอยากทำ Animation มากกว่าหนึ่งอย่างขึ้นไปล่ะ? ก็ใส่เพิ่มเข้าไปใน Tag ของ Set ได้ทันทีเลย อย่างเช่น

my_anim_3.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
    
    <translate android:fromXDelta="-100%"
        android:toXDelta="0%"
        android:fromYDelta="0%"
        android:toYDelta="0%"
        android:duration="1000" />
    
    <alpha android:fromAlpha="0"
        android:toAlpha="1"
        android:duration="800" />

</set>

        จากตัวอย่างนี้ก็เป็นการใช้ Translate กับ Alpha พร้อมๆกัน โดย Translate จะให้เลื่อน Text View จากซ้ายไปทางขวาที่ระยะเท่ากับความกว้างของ Text View ใช้เวลา 1 วินาที ส่วน Alpha จะเริ่มจาก 0% ไปยัง 100% ใช่เวลา 0.8 วินาที ดังนั้นตอนทำงานจริง Translate กับ Alpha จะเริ่มพร้อมกัน แต่ว่า Alpha จะเสร็จก่อนเพราะใช้เวลาแค่ 0.8 วินาที

        สมมติว่าอยากให้ทำ Animation อย่างหนึ่งจนเสร็จก่อน แล้วจึงจะเริ่้ม Animation ตัวต่อไปล่ะ จะต้องทำยังไง?

my_anim_4.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
    
    <translate android:fromXDelta="-100%"
        android:toXDelta="0%"
        android:fromYDelta="0%"
        android:toYDelta="0%"
        android:duration="1000" />
    
    <rotate android:fromDegrees="0"
        android:toDegrees="360"
        android:duration="1500"
        android:startOffset="1000" />

</set>

        มีการใช้ startOffset เพิ่มเข้ามา เพื่อกำหนดเวลาที่จะให้เริ่ม ดังนั้น Translate จะเริ่มทำงานทันทีเป็นเวลา 1 วินาที ส่วน Rotate จะรอเวลาผ่านไป 1 วินาทีก่อน จึงทำงาน โดยใช้เวลา 1.5 วินาที และเนื่องจากไม่ได้กำหนดจุดหมุน ดังนั้นจะอ้างอิงจุดหมุนที่มุมซ้ายบนของวัตถุนั้นๆแทน

        ถ้าใช้ Animation ซ้ำกันได้มั้ย? ย่อมได้อยู่แล้วครับ แต่ดูเรื่อง Duration กับ Start Offset ให้แม่นๆด้วย ว่าอันแรกควรใช้เวลาเท่าไรและอันต่อไปควรเริ่มเมื่อไร

my_anim_5.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
    
    <translate android:fromXDelta="0%"
        android:toXDelta="0%"
        android:fromYDelta="-300%"
        android:toYDelta="0%"
        android:duration="1000" />
    
    <translate android:fromXDelta="0%"
        android:toXDelta="50%"
        android:fromYDelta="0%"
        android:toYDelta="100%"
        android:duration="1000"
        android:startOffset="1000" />

</set>

        ก็จากตัวอย่างคร่าวๆนี้ลองเอาไปฝีกประยุกต์ดูนะ เพราะเดี๋ยวเจ้าของบล็อกจะมีบทความอื่นๆที่จะใช้เรื่องนี้ โดย Animation Resource ที่เป็นตัวอย่างทั้งหมดทำเป็นไฟล์ไว้ให้แล้ว



        สำหรับผู้ที่หลงเข้ามาอ่านคนใดต้องการไฟล์ตัวอย่างสามารถดาวน์โหลดได้ที่ Animation Resource [Google Drive]




เหล่าพันธมิตรแอนดรอยด์

Devahoy Layer Net NuuNeoI The Cheese Factory Somkiat CC Mart Routine Artit-K Arnondora Kamonway Try to be android developer Oatrice Benz Nest Studios Kotchaphan@Medium Jirawatee@Medium Travispea@Medium