הזזת תצוגות באמצעות אנימציה של תנועה אופקית

איך עושים את זה ב-Compose
‫Jetpack Compose היא ערכת הכלים המומלצת לפיתוח ממשק משתמש ב-Android. איך משתמשים באנימציות ב-Compose.

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

תרשים 1. אנימציית החלקה

במדריכים הבאים אפשר לקרוא על נושאים קשורים:

הוספת ספריית AndroidX

כדי להשתמש באנימציות שמבוססות על פיזיקה, צריך להוסיף את ספריית AndroidX לפרויקט באופן הבא:

  1. פותחים את הקובץ build.gradle של מודול האפליקציה.
  2. מוסיפים את ספריית AndroidX לקטע dependencies.

    מגניב

            dependencies {
                implementation 'androidx.dynamicanimation:dynamicanimation:1.0.0'
            }
            

    Kotlin

            dependencies {
                implementation("androidx.dynamicanimation:dynamicanimation:1.0.0")
            }
            

יצירת אנימציית הטלה

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

Kotlin

val fling = FlingAnimation(view, DynamicAnimation.SCROLL_X)

Java

FlingAnimation fling = new FlingAnimation(view, DynamicAnimation.SCROLL_X);

הגדרת מהירות

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

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

כדי להגדיר את המהירות, צריך לבצע קריאה ל-method‏ setStartVelocity() ולהעביר את המהירות בפיקסלים לשנייה. השיטה מחזירה את אובייקט ההטלה שעליו מוגדרת המהירות.

הערה: משתמשים במחלקות GestureDetector.OnGestureListener ו-VelocityTracker כדי לאחזר ולחשב את המהירות של תנועות המגע, בהתאמה.

הגדרת טווח ערכים לאנימציה

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

הערה: כשהערך של אנימציית ההטלה מגיע לערך המינימלי או המקסימלי, האנימציה מסתיימת.

כדי להגדיר את ערכי המינימום והמקסימום, צריך להפעיל את השיטות setMinValue() ו-setMaxValue(), בהתאמה. שתי השיטות מחזירות את אובייקט האנימציה שהגדרתם לו את הערך.

הגדרת חיכוך

השיטה setFriction() מאפשרת לשנות את החיכוך של האנימציה. הוא מגדיר את קצב הירידה במהירות באנימציה.

הערה: אם לא מגדירים את החיכוך בתחילת האנימציה, המערכת משתמשת בערך ברירת המחדל של החיכוך, שהוא 1.

השיטה מחזירה את האובייקט שהאנימציה שלו משתמשת בערך החיכוך שציינתם.

קוד לדוגמה

הדוגמה הבאה ממחישה תנועת החלקה אופקית. המהירות שנקלטה על ידי מעקב המהירות היא velocityX, וגבולות הגלילה מוגדרים ל-0 ול-maxScroll. החיכוך מוגדר ל-1.1.

Kotlin

FlingAnimation(view, DynamicAnimation.SCROLL_X).apply {
    setStartVelocity(-velocityX)
    setMinValue(0f)
    setMaxValue(maxScroll)
    friction = 1.1f
    start()
}

Java

FlingAnimation fling = new FlingAnimation(view, DynamicAnimation.SCROLL_X);
fling.setStartVelocity(-velocityX)
        .setMinValue(0)
        .setMaxValue(maxScroll)
        .setFriction(1.1f)
        .start();

הגדרת השינוי המינימלי שיוצג

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

אין צורך לקרוא לשיטה הזו כשמפעילים אנימציה של DynamicAnimation.ViewProperty כי השינוי המינימלי שגלוי נגזר מהמאפיין. לדוגמה:

  • ערך ברירת המחדל של השינוי המינימלי שגלוי לעין הוא פיקסל אחד למאפייני תצוגה כמו TRANSLATION_X, TRANSLATION_Y, TRANSLATION_Z, SCROLL_X ו-SCROLL_Y.
  • באנימציות שכוללות סיבוב, כמו ROTATION, ROTATION_X ו-ROTATION_Y, השינוי המינימלי שניתן לראות הוא MIN_VISIBLE_CHANGE_ROTATION_DEGREES, או 1/10 פיקסל.
  • באנימציות שמשתמשות באטימות, השינוי המינימלי שניתן לראות הוא MIN_VISIBLE_CHANGE_ALPHA, או 1/256.

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

Kotlin

anim.minimumVisibleChange = DynamicAnimation.MIN_VISIBLE_CHANGE_SCALE

Java

anim.setMinimumVisibleChange(DynamicAnimation.MIN_VISIBLE_CHANGE_SCALE);

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

חישוב ערך השינוי המינימלי שניתן לראות

כדי לחשב את ערך השינוי המינימלי שגלוי למאפיין מותאם אישית, משתמשים בנוסחה הבאה:

השינוי המינימלי שגלוי לעין = טווח הערכים של המאפיין המותאם אישית / טווח האנימציה בפיקסלים

לדוגמה, המאפיין שרוצים להוסיף לו אנימציה מתקדם מ-0 ל-100. זה תואם לשינוי של 200 פיקסלים. לפי הנוסחה, הערך המינימלי של שינוי גלוי הוא 100 חלקי 200, ששווה ל-0.5 פיקסלים.