אנימציה של גרפיקה שניתן להזזה

כדאי לנסות את התכונה 'כתיבה מהירה'
'Jetpack פיתוח נייטיב' היא ערכת הכלים המומלצת לממשק המשתמש ל-Android. איך משתמשים באנימציות ב-Compose
איור 1. פריט גרפי שניתן לשרטוט עם אנימציה.

במצבים מסוימים, תמונות צריכות להיות מונפשות. האפשרות הזו שימושית אם רוצים להציג אנימציית טעינה בהתאמה אישית שמכילה כמה תמונות, או אם רוצים שהסמל ישתנה לאחר פעולה של המשתמש. ב-Android יש שתי אפשרויות להנפשת רכיבי drawable.

האפשרות הראשונה היא להשתמש ב-AnimationDrawable. כך תוכלו לציין כמה קבצים ניתנים לציור סטטיים שיוצגו אחד אחרי השני כדי ליצור אנימציה. האפשרות השנייה היא להשתמש ב-AnimatedVectorDrawable, שמאפשר להנפיש את המאפיינים של קובץ שרטוט וקטורי.

שימוש ב-AnimationDrawable

אחת הדרכים ליצור אנימציה היא לטעון רצף של פריטים שניתן לצייר, כמו גליל של סרט. המחלקה AnimationDrawable היא הבסיס לסוגים האלה של אנימציות שניתן להזזה.

אפשר להגדיר את הפריימים של אנימציה בקוד באמצעות ה-API ברמה AnimationDrawable של המחלקה, אבל קל יותר להגדיר אותם באמצעות קובץ XML אחד שבו מפורטים הפריימים שמרכיבים את האנימציה. קובץ ה-XML של אנימציה מהסוג הזה שייך לספרייה res/drawable/ של פרויקט Android. במקרה כזה, ההוראות כוללות את הסדר והמשך הזמן של כל פריים באנימציה.

קובץ ה-XML מורכב מאלמנט <animation-list> בתור צומת הבסיס (root) ומסדרה של צמתים <item> צאצאים, שכל אחד מהם מגדיר מסגרת – משאב שניתן לציור ומשך הזמן שלו. לפניכם קובץ XML לדוגמה של אנימציה מסוג Drawable:

<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="true">
    <item android:drawable="@drawable/rocket_thrust1" android:duration="200" />
    <item android:drawable="@drawable/rocket_thrust2" android:duration="200" />
    <item android:drawable="@drawable/rocket_thrust3" android:duration="200" />
</animation-list>

האנימציה הזו פועלת במשך שלוש פריימים. הגדרת המאפיין android:oneshot של הרשימה לערך true גורמת לה להציג את התמונות ברצף פעם אחת, ואז להפסיק ולהישאר בתמונה האחרונה. אם מגדירים את android:oneshot לערך false, האנימציה תפעל בלופ.

אם שומרים את קובץ ה-XML הזה בתור rocket_thrust.xml בספרייה res/drawable/ של הפרויקט, אפשר להוסיף אותו כתמונה לרקע של View ואז להפעיל אותו באמצעות start(). דוגמה לפעילות שבה האנימציה מתווספת ל-ImageView ואז מופעלת כשנוגעים במסך:

Kotlin

private lateinit var rocketAnimation: AnimationDrawable

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.main)

    val rocketImage = findViewById<ImageView>(R.id.rocket_image).apply {
        setBackgroundResource(R.drawable.rocket_thrust)
        rocketAnimation = background as AnimationDrawable
    }

    rocketImage.setOnClickListener({ rocketAnimation.start() })
}

Java

AnimationDrawable rocketAnimation;

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

  ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
  rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
  rocketAnimation = (AnimationDrawable) rocketImage.getBackground();

  rocketImage.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
        rocketAnimation.start();
      }
  });
}

חשוב לציין שאי אפשר לקרוא לשיטה start() ב-AnimationDrawable במהלך השיטה onCreate() ב-Activity, כי ה-AnimationDrawable עדיין לא מצורף לחלון באופן מלא. כדי להפעיל את האנימציה באופן מיידי, בלי צורך באינטראקציה, אפשר להפעיל אותה מהשיטה onStart() ב-Activity, שנקראת כשמערכת Android מציגה את התצוגה במסך.

למידע נוסף על תחביר ה-XML ועל התגים והמאפיינים הזמינים, ראו משאבי אנימציה.

שימוש ב-AnimationVectorDrawable

פריט גרפי וקטורי שניתן להזזה הוא סוג של פריט גרפי שניתן להזזה, שלא ניתן להציג אותו בצורה מפוקסלת או מטושטשת. הקלאס AnimatedVectorDrawable – וגם AnimatedVectorDrawableCompat לצורך תאימות לאחור – מאפשרים ליצור אנימציה של המאפיינים של אובייקט גרפי שניתן לציור באמצעות וקטור, כמו סיבוב או שינוי נתוני הנתיב כדי להפוך אותו לתמונה אחרת.

בדרך כלל מגדירים רכיבי גרפיקה מונפשים של וקטור שניתן לציור בשלושה קובצי XML:

  • פריט גרפי וקטורי שניתן לשרטוט עם הרכיב <vector> ב-res/drawable/.
  • פריט גרפי וקטורי שניתן לשרטוט עם רכיב <animated-vector> ב-res/drawable/.
  • אנימטור אחד או יותר של אובייקטים עם הרכיב <objectAnimator> ב-res/animator/.

רכיבים וקטוריים מונפשים יכולים להוסיף אנימציה למאפיינים של הרכיבים <group> ו-<path>. הרכיב <group> מגדיר קבוצה של נתיבים או של קבוצות משנה, והרכיב <path> מגדיר את הנתיבים לשרטוט.

כשמגדירים פריט גרפי וקטורי שרוצים ליצור אנימציה, צריך להשתמש במאפיין android:name כדי להקצות שם ייחודי לקבוצות ולנתיבים, כדי להפנות אליהם מהגדרות האנימטורים. לדוגמה:

res/drawable/vectordrawable.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="64dp"
    android:width="64dp"
    android:viewportHeight="600"
    android:viewportWidth="600">
    <group
        android:name="rotationGroup"
        android:pivotX="300.0"
        android:pivotY="300.0"
        android:rotation="45.0" >
        <path
            android:name="v"
            android:fillColor="#000000"
            android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
    </group>
</vector>

ההגדרה של קובץ ה-vector drawable האנימציה מתייחסת לקבוצות ולנתיבי קובץ ה-vector drawable לפי השמות שלהם:

res/drawable/animatorvectordrawable.xml

<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
  android:drawable="@drawable/vectordrawable" >
    <target
        android:name="rotationGroup"
        android:animation="@animator/rotation" />
    <target
        android:name="v"
        android:animation="@animator/path_morph" />
</animated-vector>

הגדרות האנימציה מייצגות אובייקטים של ObjectAnimator או AnimatorSet. האנימטור הראשון בדוגמה הזו מסובב את קבוצת היעד ב-360 מעלות:

res/animator/rotation.xml

<objectAnimator
    android:duration="6000"
    android:propertyName="rotation"
    android:valueFrom="0"
    android:valueTo="360" />

האנימטור השני בדוגמה הזו מעצב את הנתיב של פריט השרטוט הווקטורי מצורה אחת לאחרת. הנתיבים צריכים להיות תואמים לטרנספורמציה: הם צריכים לכלול את אותו מספר של פקודות ואותו מספר פרמטרים בכל פקודה.

res/animator/path_morph.xml

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:duration="3000"
        android:propertyName="pathData"
        android:valueFrom="M300,70 l 0,-70 70,70 0,0   -70,70z"
        android:valueTo="M300,70 l 0,-70 70,0  0,140 -70,0 z"
        android:valueType="pathType" />
</set>

זו התוצאה של AnimatedVectorDrawable:

איור 2. AnimatedVectorDrawable.

תצוגה מקדימה של פריט וקטורי ניתן להזזה (AVD)

הכלי Animated Vector Drawable ב-Android Studio מאפשר להציג תצוגה מקדימה של משאבי drawable מונפשים. הכלי הזה עוזר לכם להציג תצוגה מקדימה של המשאבים <animation-list>,‏ <animated-vector> ו-<animated-selector> ב-Android Studio, ומאפשר לשפר בקלות את האנימציות בהתאמה אישית.

משתמש צופה בתצוגה מקדימה ומפעילים אנימציה ב-Android Studio
איור 3. הכלי מונפש Vector Drawable ב-Android Studio.

מידע נוסף זמין במאמר העזרה של ה-API של AnimatedVectorDrawable.