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

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

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

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

שימוש ב-AnimationDrawable

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

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

קובץ ה-XML מורכב מרכיב <animation-list> כצומת הבסיס ומסדרה של צמתי צאצא <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 ועל התגים והמאפיינים הזמינים זמין במאמר משאבי אנימציה.

שימוש ב-AnimatedVectorDrawable

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

בדרך כלל מגדירים אנימציות של וקטורים בפורמט drawable בשלושה קובצי 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>

ההגדרה של ה-Animated 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

<set xmlns:android="http://schemas.android.com/apk/res/android">
  <objectAnimator
      android:duration="6000"
      android:propertyName="rotation"
      android:valueFrom="0"
      android:valueTo="360" />
</set>

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

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. הכלי Animated Vector Drawable ב-Android Studio.

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