28 กันยายน 2555

[Android Code] สร้างการเคลื่อนไหวง่ายๆ ด้วยคลาส TranslateAnimation


อ่ะต่ออีกบทความไปเลย จะได้จบพื้นฐานเรื่องคลาส Animation
คราวนี้เป็นคลาส TranslateAnimation ที่เอาไว้กำหนดให้วัตถุเคลื่อนที่


Main.java
package app.akexorcist.translateanimation;

import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;

public class Main extends Activity {
    RelativeLayout layout;
    ImageView imgLogo;
    Animation anim;

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        layout = (RelativeLayout)findViewById(R.id.layout);
        imgLogo = (ImageView)findViewById(R.id.imgLogo);

        Button btnNormalScale = (Button)findViewById(R.id.btnNormalScale);
        btnNormalScale.setOnClickListener(new OnClickListener() {
            public void onClick(View arg0) {
                anim = new TranslateAnimation(0, 100, 0, 100);
                anim.setDuration(1000);
                imgLogo.startAnimation(anim);
            }
        });

        Button btnToggleScale = (Button)findViewById(R.id.btnToggleScale);
        btnToggleScale.setOnClickListener(new OnClickListener() {
            public void onClick(View arg0) {
                anim = new TranslateAnimation
                        (Animation.RELATIVE_TO_PARENT, (float)0
                        , Animation.RELATIVE_TO_PARENT, (float)0.25
                        , Animation.RELATIVE_TO_PARENT, (float)0
                        , Animation.RELATIVE_TO_PARENT, (float)0.25);
                anim.initialize(imgLogo.getWidth(), imgLogo.getHeight()
                        , layout.getWidth(), layout.getHeight());
                anim.setDuration(1000);
                imgLogo.startAnimation(anim);
            }
        });
    }
}


เริ่มจาก btnNormalScale กันก่อนเลย ก็จะเป็นการเคลื่อนที่แบบเบสิก
โดยจุดเริ่มต้นจะอ้างอิงจากตำแหน่งปัจจุบันของวัตถุเป็นพิกัด 0, 0
เวลาต้องการเคลื่อนวัตถุไปที่ตำแหน่งใดก็ให้ระบุพิกัดที่ต้องการ อย่างเช่น
anim = new TranslateAnimation(0, 100, 0, -200);
จากคำสั่งนี้ก็คือการกำหนดให้ imgLogo เคลื่อนที่จากตำแหน่ง 0, 0
หรือก็คือตำแหน่งปกติให้เขยิบไปทางแกน X ไป 100 พิกเซล
(ค่าเป็น + คือทางขวามือของวัตถุ และค่าเป็น - คือทางซ้ายมือของวัตถุ)
และกำหนดให้เขยิบไปทางแกน Y ไป -200 พิกเซล
(ค่าเป็น + คือเลื่อนลงข้างล่าง ค่าเป็น - คือเลื่อนขึ้นข้างบน)

แหล่งที่มาของภาพโลโก้



สำหรับ btnToggleScale ก็จะเป็นการอ้างอิงตำแหน่งเคลื่อนที่อีกแบบหนึ่ง
โดยที่จะมีการอ้างอิงจากขอบเขตของวัตถุที่จะอ้างอิง
อย่างเช่นอ้างอิงจากขนาดของตัววัตถุเอง หรือขนาดของ Parent ก็ได้
การกำหนดตำแหน่งในคำสั่งนี้จะกำหนดเป็นอัตราส่วนจากขนาดที่ใช้อ้างอิง
โดยจะต้องมีการกำหนดค่าสำหรับอ้างอิงให้กับ TranslateAnimation ด้วย
anim.initialize(imgLogo.getWidth(), imgLogo.getHeight() , layout.getWidth(), layout.getHeight());
คำสั่งนี้ก็จะเป็นการกำหนดขนาดของวัตถุโดยอิงจากความกว้างของ imgLogo
และความสูงของวัตถุก็อิงจากความสูงของ imgLogo
ส่วนความกว้างและความสูงของ Parent ก็อิงจาก layout แทน
ซึ่งเป็น RelativeLayout ที่ imgLogo อยู่ (อย่าลืมประกาศ Object ให้ layout ล่ะ)

ในการกำหนดว่าจะอ้างอิงขอบเขตจากอะไร จะมีด้วยกันสามแบบคือ
ABSOLUTE, RELATIVE_TO_SELF และ RELATIVE_TO_PARENT
โดยที่ ABSOLUTE อันนี้เจ้าของบล็อกก็ไม่ค่อยแน่ใจมากนัก
แต่เข้าใจว่าเป็นการกำหนดขอบเขตโดยอ้างอิงจากขนาดหน้าจอ
ส่วน RELATIVE_TO_SELF อันนี้จะอ้างอิงจากขนาดของตัววัตถุเอง
และ RELATIVE_TO_PARENT ก็จะอ้างอิงจากขนาดของ PARENT 
ในการกำหนดพิกัดก็จะใช้เป็นอัตราส่วน โดย 0 คือตำแหน่งเริ่มต้น

สมมติว่าเจ้าของบล็อกกำหนดตำแหน่งเริ่มต้นทั้ง X และ Y เป็น 0 
และกำหนดให้ตำแหน่งปลายทางที่จะเคลื่อนที่ไปทั้ง X และ Y เป็น 5 
ก็จะหมายถึง 5 เท่าของขนาดที่อ้างอิง ถ้าสมมติอีกว่าอ้างอิงจาก PARENT
แล้ว PARENT มีขนาด 300 x 300 ก็จะเคลื่อนที่จาก (0, 0) ไปที่ (1500, 1500)
ดังนั้นจากตัวอย่างก็จะใช้คำสั่งดังนี้
anim = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, (float)0 , Animation.RELATIVE_TO_PARENT, (float)-0.25 , Animation.RELATIVE_TO_PARENT, (float)0 , Animation.RELATIVE_TO_PARENT, (float)-0.25);
ก็คือกำหนดขนาดที่อ้างอิงทั้งหมดให้เป็น PARENT (ซึ่งก็คือ layout นั่นเอง)
ให้เคลื่อนที่จาก (0, 0) (ตำแหน่งปกติของวัตถุ) แล้วเคลื่อนที่ -0.25 ทั้ง X และ Y
สมมติว่า layout มีขนาด 480 x 800 เอา -0.25 ไปคูณ 480 จะได้ -120
และ 800 คูณ -0.25 จะได้ -200 ก็จะได้เป็น (-120, -200)
ดังนั้นวัตถุก็จะเคลื่อนที่จาก (0, 0) ไปยังตำแหน่ง (-120, -200) นั่นเอง

แหล่งที่มาของภาพโลโก้
Seth Dennon / CC BY 3.0


main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
    <Button
        android:id="@+id/btnNormalScale"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:text="Normal Translate" />
    <Button
        android:id="@+id/btnToggleScale"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:text="Toggle Translate" />
    <ImageView
        android:id="@+id/imgLogo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:src="@drawable/samplelogo" />
</RelativeLayout>


AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="app.akexorcist.translateanimation"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".Main"
            android:label="@string/title_activity_main" 
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

สำหรับผู้ที่หลงเข้ามาอ่านที่ต้องการไฟล์ตัวอย่างสามารถดาวน์โหลดได้จาก
Animation-Translate [Google Drive] หรือ Android-AnimationTranslate [GitHub]

บทความที่เกี่ยวกับคลาส Animation


จบแล้ว สามบทความรวด 

ไว้ต่อด้วยเรื่อง Interpolator ทีหลัง





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

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