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

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

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

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

שימוש במצב אנימציה

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

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

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

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)

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

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

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