27 กันยายน 2555

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


คราวนี้ก็มาถึงเรื่องของคลาส RotateAnimation กันบ้าง
หรือก็คือคลาสที่ควบคุมการหมุนวัตถุนั่นเอง



Main.java

package app.akexorcist.rotateanimation;

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.RotateAnimation;
import android.widget.Button;
import android.widget.ImageView;

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

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

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

        Button btnRotateCenter = (Button)findViewById(R.id.btnRotateCenter);
        btnRotateCenter.setOnClickListener(new OnClickListener() {
            public void onClick(View arg0) {
                anim = new RotateAnimation(0, 360
                        , imgLogo.getWidth() / 2
                        , imgLogo.getHeight() / 2);
                anim.setDuration(1000);
                imgLogo.startAnimation(anim);
            }
        });

        Button btnContinueRotate = (Button)findViewById(R.id.btnContinueRotate);
        btnContinueRotate.setOnClickListener(new OnClickListener() {
            float angle = 0, adj = 45;
            public void onClick(View arg0) {
                anim = new RotateAnimation(angle, angle + adj
                        , imgLogo.getWidth() / 2
                        , imgLogo.getHeight() / 2);
                anim.setDuration(500);
                anim.setFillEnabled(true);
                anim.setFillAfter(true);
                imgLogo.startAnimation(anim);
                angle += adj;
            }
        });
    }
}

สำหรับคำสั่งใน Event Listener ของ btnNormalRotate 
ก็จะเป็นคำสั่งเบสิกที่ให้ imgLogo หมุน 360 องศา
แต่พอรันโปรแกรมจริงๆก็จะพบว่า imgLogo ไม่ได้หมุนกลางภาพ 
แต่จะหมุนรอบมุมซ้ายบนของภาพ ทั้งนี้ก็เพราะว่าคำสั่ง 
anim = new RotateAnimation(0, 360);
จะอ้างอิงจุดหมุนที่พิกัดซ้ายบนสุดของภาพ (0, 0)
จึงทำให้ภาพหมุนรอบพิกัดดังกล่าวแทน (ดูภาพข้างล่าง)

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


ทีนี้มาดูที่ Event Listener ของ btnRotateCenter กันบ้าง
จะเห็นว่าคำสั่งเปลี่ยนไปโดยจะมีให้กำหนดจุดหมุนได้

เจ้าของบล็อกได้กำหนดจุดหมุนอยู่ที่กึ่งกลางภาพ
anim = new RotateAnimation(0, 360, imgLogo.getWidth()/2, imgLogo.getHeight()/2);
โดยพิกัดแกน X อ้างอิงจากความกว้างของภาพหารด้วย 2
และพิกัดแกน Y อ้างอิงจากความสูงของภาพหารด้วย 2
เพียงเท่านี้ภาพก็จะหมุนอยู่ตรงกลางแล้ว (ดูภาพข้างล่าง)

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


ทีนี้มาดูที่ Event Listener ของ btnContinueRotate กันต่อ

จุดหมุนก็จะเหมือนกับ btnRotateCenter นั่นแหละ 
แต่ว่ามุมในการหมุน เจ้าของบล็อกจะให้หมุนทีละ 45 องศา
โดยสร้างตัวแปรมาเก็บค่ามุมไว้ ซึ่งก็คือ angle กับ adj
float angle = 0, adj = 45;
ให้ angle เก็บค่ามุม ณ ตอนนั้น และ adj เป็นองศาที่จะหมุน
โดยจะให้เริ่มหมุนจาก angle ไปยัง angle + adj 
ซึ่งก็คือหมุนตามเข็นนาฬิกาไป 45 องศานั่นเอง
จากนั้นก็จะมีการใช้คำสั่งเพิ่มเข้ามาสองคำสั่ง คือ
anim.setFillEnabled(true);

anim.setFillAfter(true);
คำสั่งดังกล่าวก็คือ เมื่อภาพหมุนเสร็จแล้วให้คงสถานะภาพไว้เลย
เพราะถ้าไม่กำหนด ภาพจะหมุนจาก 0 ไป 45 องศา
เมื่อหมุนเสร็จแล้วภาพจะกลับมาอยู่ที่ตำแหน่ง 0 องศาเหมือนเดิม
คำสั่ง setFillAfter ก็จะเป็นการกำหนดให้ภาพคงสถานะสุดท้ายไว้
จากนั้นก็ให้ตัวแปร angle อัพเดทค่ามุมที่หมุนเข้าไปแทนที่ค่าเก่า
ทีนี้เวลากดปุ่ม btnContinueRotate ภาพก็จะหมุนทีละ 45 องศาเรื่อยๆ

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



main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
    <Button
        android:id="@+id/btnNormalRotate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_toLeftOf="@+id/btnRotateCenter"
        android:text="Normal Rotate" />
    <Button
        android:id="@+id/btnRotateCenter"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:text="Rotate Center" />
    <Button
        android:id="@+id/btnContinueRotate"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_toRightOf="@+id/btnRotateCenter"
        android:text="Continue Rotate" />
    <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.rotateanimation"
    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>

สำหรับผู้ที่หลงเข้ามาอ่านที่ต้องการไฟล์ตัวอย่างสามารถดาวน์โหลดได้จาก


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

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