יום ראשון, נובמבר 14

אנימציה - 1

אנימציה היא התהליך בו אלמנטים בתצוגה משתנים על ציר הזמן. השינוי יכול להיות בגודל, בצורה, בצבע, במיקום או בכיוון.
ישנן 3 שיטות לביצוע אנימציה באנדרואיד
Frame by Frame
Layout Animation
View Animation

בפוסט הזה נציג את השיטה הראשונה, שהיא גם הפשוטה ביותר - Frame By Frame. פוסטים עם שתי השיטות האחרות - בדרך. העיקרון של ה- Frame By Frame: הרצה של תמונות עוקבות כדי ליצור האשליה של תנועה או שינוי דינמי. ההרצה יכולה להיות חד פעמית (one shot), או מחזורית. ה-Frame By Frame -class משתמשת במתודות של class ה- AnimationDrawable שהינו הרחבה של ה-Drawable.
נעבור לפרויקט שלנו - כרגיל, כל קבצי הפרויקט ניתנים להורדה - ראה לינק בסוף.

כמנהגנו נתחיל עם הצגת תמונת ה-UI המתקבלת לאחר הרצת התוכנית:



התצוגה כוללת כפתור הפעל\הפסק (הכיתוב על הכפתור משתנה בהתאם למצב), ותמונת Smiley. בתוך ספריית ה-drawable שמורים למעשה 6 תמונות של Smiley עם שינוי קל בין התמונות. הרצת האנימציה תגרום לתמונות להתחלף כך שה-Smiley יקפוץ למעלה ולמטה ויסתובב סביב עצמו.

נתרכז ב-4 הקבצים אותם ערכנו:
  1. קובץ ה-Layout, שמו res/layout/main.xml
  2. קובץ האנימציה,  /res/drawable/fbfanimation.xml
  3. הקובץ strings.xml
  4. וכמובן ובעיקר - myAnimationFbF.java
מלבד 4 הקבצים האלה, הוספנו כאמור את 6 התמונות המרכיבות את האנימציה ב-drawable.
     קובץ ה-layout  רגיל ופשוט: Linear Layמוגדרים בו כפתור הפעלה ושאר המסך שייך לאלמנט התמונה ImageView. הנה תוכן קובץ ה-Layout:

    1. <?xml version="1.0" encoding="utf-8"?>
    2. android:orientation="vertical"
    3. android:layout_width="fill_parent"
    4. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    5. android:layout_height="fill_parent"
    6. >
    7. <Button
    8. android:id="@+id/on_off"
    9. android:layout_width="wrap_content"
    10. android:layout_height="wrap_content"
    11. android:text="@string/button_on"
    12. android:layout_gravity="center"/>
    13. <ImageView
    14. android:id="@+id/image_animation"
    15. android:layout_width="fill_parent"
    16. android:layout_height="wrap_content"
    17. />
    18. </LinearLayout>
    הגדרות ה-Button וה-Image View מתחילות בשורה 7 ו-13 בהתאמה.
    שורה 11 - הכיתוב על הכפתור יקבע בקובץ strings.xml. נותן גמישות...
    בשורה 12, מאפיין ה-gravity קובע את מיקום הכפתור בבמרכז.


    קובץ האנימציה fbfanimation.xml:

    1. <animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    2. android:oneshot="false">
    3. <item android:drawable="@drawable/b1" android:duration="100" />
    4. <item android:drawable="@drawable/b2" android:duration="100" />
    5. <item android:drawable="@drawable/b3" android:duration="100" />
    6. <item android:drawable="@drawable/b4" android:duration="100" />
    7. <item android:drawable="@drawable/b5" android:duration="100" />
    8. <item android:drawable="@drawable/b6" android:duration="100" />
    9. </animation-list>
    הקובץ מתאר את התמונות מהן תבנה האנימציה, במקרה הנ"ל 6 תמונות, שהקבצים שלהן נמצאים ב- res/drawable
    שורה 2: oneshot = false, כך שרצף האנימציה יהיה אינסופי - עד שיעצר ע"י פקודה.
    שורות 3-8: הקבצים שמרכיבים את האנימציה.

    הקובץ strings.xml, כרגיל, מחזיק שמות של אלמנטים באפליקציה.  השמות המעניינים כאן הם הכיתובים על הכפתור. במצב מופעל יופיע על הכפתור "button off" ובמצב מופסק "button on". (שורה 3 - שארית מיותרת, אפר למחוק אותה).

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <resources>
    3.     <string name="hello">Hello World, FrameAnimationActivity!</string>
    4.     <string name="app_name">frameByFrameAnimation</string>
    5.      <string name="button_on">Animation On</string>
    6.      <string name="button_off">Animation Off</string>
    7.     
    8. </resources>

    נעבור לקובץ הג'אווה. המימוש נעשה עם class יחיד בשם MyAnimationFbF ומתודה אחת: onCreate.


    התוכנית לפניכם:
    1. public class MyAnimationFbF extends Activity {
    2.     AnimationDrawable imageAnimated;
    3.     Button buttonOnOff;
    4.     @Override
    5.     public void onCreate(Bundle savedInstanceState)
    6.     {
    7.         super.onCreate(savedInstanceState);
    8.         setContentView(R.layout.main);
    9.         ImageView    imageView = (ImageView)findViewById(R.id.image_animation);
    10.         imageView.setBackgroundResource(R.drawable.fbfanimation);
    11.         imageAnimated =    (AnimationDrawable) imageView.getBackground();
    12.         buttonOnOff = (Button)findViewById(R.id.on_off);
    13.         buttonOnOff.setOnClickListener(new Button.OnClickListener(){
    14.             public void onClick(View v)
    15.             {
    16.                 if (imageAnimated.isRunning())
    17.                 {
    18.                     imageAnimated.stop();
    19.                     buttonOnOff.setText(getString(R.string.button_on));
    20.                 }
    21.                 else
    22.                 {
    23.                     imageAnimated.start();
    24.                     buttonOnOff.setText(getString(R.string.button_off));
    25.                 }
    26.             }
    27.         });
    28.     }

    נתעכב על שורות 9-11 ונציג אותן שוב כאן לשם הנוחות:

    1.       ImageView    imageView = (ImageView)findViewById(R.id.image_animation);
    2.         imageView.setBackgroundResource(R.drawable.fbfanimation);
    3.         imageAnimated =  (AnimationDrawable)imageView.getBackground();

    שורה 9 בקובץ (שורה 1 כאן): שליפת ה ImageView מה-layout עפ"י ה-id שלו.
    שורה 10 (שורה 2 כאן):  קביעת רקע לאובייקט imageView. הרקע נקבע להיות הקובץ fbfanimation.xml, שמכיל את סדרת תמונות האנימציה.
    שורה 11 (שורה 3 כאן):  יצירת אובייקט לאנימציה מסוג  AnimationDrawable.

    יצרנו אובייקט לאנימציה המבוסס על קובץ האנימציה שהכנו.
    כעת אפשר להפעיל את המתודות של האובייקט. להפעלת והפסקת האנימציה נשתמש במתודות run ו-stop בתוך ה-callback של כפתור ההפעלה (onClick). נשתמש גם ב isRunning לבדיקת סטטוס הריצה.  שורות 14-27 מוצגות כאן שוב:
    1.             public void onClick(View v)
    2.             {
    3.                 if (imageAnimated.isRunning())
    4.                 {
    5.                     imageAnimated.stop();
    6.                     buttonOnOff.setText(getString(R.string.button_on));
    7.                 }
    8.                 else
    9.                 {
    10.                     imageAnimated.start();
    11.                     buttonOnOff.setText(getString(R.string.button_off));
    12.                 }
    13.             }
    14.         });
    נראה פשוט.
    שורות 6 ו-11 כאן למעלה, משנות את הכיתוב על הכפתור. הטקסט נשלף מהקובץ strings.xml. כן, בשביל לשמור על הגמישות...
    להורדת קבצי הפרויקט לחץ על הקישור.

    תגובה 1:

    1. הייתי רוצה להוסיף גם את ההסבר איך מפעילים אנימציה אוטומטי :

      public class MyAnimation extends Activity {

      AnimationDrawable animation;

      @Override
      public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);

      animation = new AnimationDrawable();
      animation.addFrame(getResources().getDrawable(R.drawable.pic1), 100);
      animation.addFrame(getResources().getDrawable(R.drawable.pic2), 100);
      animation.addFrame(getResources().getDrawable(R.drawable.pic3), 100);
      animation.setOneShot(false);

      ImageView imageAnim = (ImageView) findViewById(R.id.myimageview);
      imageAnim.setBackgroundDrawable(animation);

      // run the start() method later on the UI thread
      imageAnim.post(new Starter());

      }

      class Starter implements Runnable {

      public void run() {
      animation.start();
      }


      }
      }

      השבמחק