תנועה שמבוססת על פיזיקה מונעת על ידי כוח. כוח קפיץ הוא דוגמה לכוח כזה שמנחה את האינטראקטיביות והתנועה. לכוח של קפיץ יש את המאפיינים הבאים: שיכוך וקשיחות. באנימציה שמבוססת על קפיץ, הערך והמהירות מחושבים על סמך כוח הקפיץ שמופעל על כל פריים.
אם רוצים שהאנימציות באפליקציה יואטו רק בכיוון אחד, כדאי להשתמש במקום זאת באנימציית הטלה שמבוססת על חיכוך.
מחזור החיים של אנימציה של קפיץ
באנימציה שמבוססת על קפיץ, המחלקה SpringForce מאפשרת להתאים אישית את קשיחות הקפיץ, את יחס השיכוך ואת המיקום הסופי שלו. ברגע שהאנימציה מתחילה, כוח הקפיץ מעדכן את ערך האנימציה ואת המהירות בכל פריים. האנימציה נמשכת
עד שכוח הקפיץ מגיע לשיווי משקל.
לדוגמה, אם גוררים סמל של אפליקציה על המסך ואז משחררים אותו על ידי הרמת האצבע מהסמל, הסמל נמשך חזרה למקום המקורי שלו על ידי כוח בלתי נראה אבל מוכר.
בתמונה 1 אפשר לראות אפקט דומה של קפיצה. סימן הפלוס (+) באמצע העיגול מציין את הכוח שמופעל באמצעות תנועת מגע.
יצירת אנימציה של קפיץ
השלבים הכלליים ליצירת אנימציה של קפיץ לאפליקציה הם:
- מוסיפים את ספריית התמיכה כדי להשתמש במחלקות האנימציה של הקפיץ, צריך להוסיף את ספריית התמיכה לפרויקט.
- יצירת אנימציה של קפיצה:
השלב העיקרי הוא ליצור מופע של המחלקה
SpringAnimationולהגדיר את הפרמטרים של התנהגות התנועה. - (אופציונלי) רישום של רכיבי Listener:
רושמים רכיבי Listener כדי לעקוב אחרי שינויים במחזור החיים של האנימציה ואחרי עדכונים של ערכי האנימציה.
הערה: צריך לרשום את מאזין העדכונים רק אם נדרש עדכון לכל פריים בשינויים של ערך האנימציה. מאזין לעדכונים מונע את האפשרות שהאנימציה תפעל בשרשור נפרד.
- (אופציונלי) מסירים listeners: מסירים listeners שכבר לא בשימוש.
- (אופציונלי) הגדרת ערך התחלתי: אפשר להתאים אישית את ערך ההתחלה של האנימציה.
- (אופציונלי) מגדירים טווח ערכים: מגדירים את טווח הערכים של האנימציה כדי להגביל את הערכים לטווח המינימלי והמקסימלי.
- (אופציונלי) הגדרת מהירות התחלתית: מגדירים את המהירות ההתחלתית של האנימציה.
- (אופציונלי) הגדרת מאפייני הקפיץ: מגדירים את יחס השיכוך ואת הקשיחות של הקפיץ.
- (אופציונלי) יוצרים קפיץ בהתאמה אישית: יוצרים קפיץ בהתאמה אישית אם לא רוצים להשתמש בקפיץ שמוגדר כברירת מחדל או אם רוצים להשתמש באותו קפיץ לאורך כל האנימציה.
- הפעלת האנימציה: הפעלת האנימציה של הקפיץ.
- (אופציונלי) ביטול האנימציה: ביטול האנימציה במקרה שהמשתמש יוצא מהאפליקציה או מהתצוגה באופן פתאומי או שהתצוגה הופכת לבלתי נראית.
בקטעים הבאים נסביר בפירוט את השלבים הכלליים ליצירת אנימציה של קפיץ.
הוספת ספריית התמיכה
כדי להשתמש בספריית התמיכה מבוססת-הפיזיקה, צריך להוסיף את ספריית התמיכה לפרויקט באופן הבא:
- פותחים את הקובץ
build.gradleשל מודול האפליקציה. מוסיפים את ספריית התמיכה לקטע
dependencies.מגניב
dependencies { def dynamicanimation_version = '1.0.0' implementation "androidx.dynamicanimation:dynamicanimation:$dynamicanimation_version" }
Kotlin
dependencies { val dynamicanimation_version = "1.0.0" implementation("androidx.dynamicanimation:dynamicanimation:$dynamicanimation_version") }
כדי לראות את הגרסאות הנוכחיות של הספרייה הזו, אפשר לעיין במידע על Dynamicanimation בדף versions.
יצירת אנימציה של קפיץ
המחלקות SpringAnimation מאפשרות ליצור אנימציה של קפיץ לאובייקט. כדי ליצור אנימציה של קפיץ, צריך ליצור מופע של המחלקה SpringAnimation ולספק אובייקט, מאפיין של האובייקט שרוצים להנפיש ומיקום קפיץ סופי אופציונלי שבו רוצים שהאנימציה תסתיים.
הערה: כשיוצרים אנימציה של קפיץ, לא חייבים לציין את המיקום הסופי של הקפיץ. עם זאת, חובה להגדיר אותו לפני שמתחילים את האנימציה.
Kotlin
val springAnim = findViewById<View>(R.id.imageView).let { img -> // Setting up a spring animation to animate the view’s translationY property with the final // spring position at 0. SpringAnimation(img, DynamicAnimation.TRANSLATION_Y, 0f) }
Java
final View img = findViewById(R.id.imageView); // Setting up a spring animation to animate the view’s translationY property with the final // spring position at 0. final SpringAnimation springAnim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y, 0);
אנימציה מבוססת-קפיץ יכולה להנפיש תצוגות במסך על ידי שינוי המאפיינים בפועל באובייקטים של התצוגה. התצוגות הבאות זמינות במערכת:
ALPHA: מייצג את שקיפות האלפא בתצוגה. ערך ברירת המחדל הוא 1 (אטום), וערך של 0 מייצג שקיפות מלאה (לא נראה).-
TRANSLATION_X,TRANSLATION_Yו-TRANSLATION_Z: המאפיינים האלה קובעים את המיקום של התצוגה כדלתא מהקואורדינטה השמאלית, מהקואורדינטה העליונה ומהגובה שלה, שמוגדרים על ידי מאגר הפריסה שלה.TRANSLATION_Xמתאר את הקואורדינטה השמאלית.TRANSLATION_Yמתאר את הקואורדינטה העליונה.TRANSLATION_Zמתאר את עומק התצוגה ביחס לגובה שלה.
-
ROTATION,ROTATION_X, ו-ROTATION_Y: המאפיינים האלה קובעים את הסיבוב בדו-ממד (המאפייןrotation) ובתלת-ממד סביב נקודת המשען. -
SCROLL_Xו-SCROLL_Y: המאפיינים האלה מציינים את היסט הגלילה של הקצה השמאלי והקצה העליון של המקור בפיקסלים. הוא גם מציין את המיקום מבחינת מידת הגלילה בדף. -
SCALE_Xו-SCALE_Y: המאפיינים האלה שולטים בשינוי קנה המידה של תצוגה דו-ממדית סביב נקודת הציר שלה. -
X,Yו-Z: אלה מאפייני כלי בסיסיים שמתארים את המיקום הסופי של התצוגה במאגר שלה.-
Xהוא סכום של הערך השמאלי ושלTRANSLATION_X. Yהוא סכום של הערך העליון ושלTRANSLATION_Y.-
Zהוא סכום של ערך הגובה ושלTRANSLATION_Z.
-
רישום של listeners
המחלקות DynamicAnimation מספקות שני מאזינים: OnAnimationUpdateListener ו-OnAnimationEndListener.
המאזינים האלה מאזינים לעדכונים באנימציה, למשל כשיש שינוי בערך האנימציה וכשהאנימציה מסתיימת.
OnAnimationUpdateListener
אם רוצים להנפיש כמה תצוגות כדי ליצור אנימציה משורשרת, אפשר להגדיר את OnAnimationUpdateListener כך שיקבל קריאה חוזרת בכל פעם שיש שינוי במאפיין של התצוגה הנוכחית. הקריאה החוזרת מודיעה לתצוגה השנייה לעדכן את מיקום הקפיץ שלה
בהתאם לשינוי שחל במאפיין של התצוגה הנוכחית. כדי לרשום את ה-listener:
-
מבצעים קריאה ל-method
addUpdateListener()ומצרפים את ה-listener לאנימציה.הערה: צריך לרשום את מאזין העדכונים לפני שהאנימציה מתחילה. עם זאת, צריך לרשום את מאזין העדכונים רק אם צריך עדכון לכל פריים בשינויים של ערך האנימציה. מאזין עדכונים מונע את האפשרות שהאנימציה תפעל בשרשור נפרד.
-
אפשר לבטל את השיטה
onAnimationUpdate()כדי להודיע לקורא על השינוי באובייקט הנוכחי. בדוגמת הקוד הבאה אפשר לראות איך משתמשים ב-OnAnimationUpdateListener.
Kotlin
// Setting up a spring animation to animate the view1 and view2 translationX and translationY properties val (anim1X, anim1Y) = findViewById<View>(R.id.view1).let { view1 -> SpringAnimation(view1, DynamicAnimation.TRANSLATION_X) to SpringAnimation(view1, DynamicAnimation.TRANSLATION_Y) } val (anim2X, anim2Y) = findViewById<View>(R.id.view2).let { view2 -> SpringAnimation(view2, DynamicAnimation.TRANSLATION_X) to SpringAnimation(view2, DynamicAnimation.TRANSLATION_Y) } // Registering the update listener anim1X.addUpdateListener { _, value, _ -> // Overriding the method to notify view2 about the change in the view1’s property. anim2X.animateToFinalPosition(value) } anim1Y.addUpdateListener { _, value, _ -> anim2Y.animateToFinalPosition(value) }
Java
// Creating two views to demonstrate the registration of the update listener. final View view1 = findViewById(R.id.view1); final View view2 = findViewById(R.id.view2); // Setting up a spring animation to animate the view1 and view2 translationX and translationY properties final SpringAnimation anim1X = new SpringAnimation(view1, DynamicAnimation.TRANSLATION_X); final SpringAnimation anim1Y = new SpringAnimation(view1, DynamicAnimation.TRANSLATION_Y); final SpringAnimation anim2X = new SpringAnimation(view2, DynamicAnimation.TRANSLATION_X); final SpringAnimation anim2Y = new SpringAnimation(view2, DynamicAnimation.TRANSLATION_Y); // Registering the update listener anim1X.addUpdateListener(new DynamicAnimation.OnAnimationUpdateListener() { // Overriding the method to notify view2 about the change in the view1’s property. @Override public void onAnimationUpdate(DynamicAnimation dynamicAnimation, float value, float velocity) { anim2X.animateToFinalPosition(value); } }); anim1Y.addUpdateListener(new DynamicAnimation.OnAnimationUpdateListener() { @Override public void onAnimationUpdate(DynamicAnimation dynamicAnimation, float value, float velocity) { anim2Y.animateToFinalPosition(value); } });
OnAnimationEndListener
OnAnimationEndListener
מודיע על סיום אנימציה. אפשר להגדיר את רכיב ה-listener כך שיקבל קריאה חוזרת (callback) בכל פעם שהאנימציה מגיעה לשיווי משקל או שהיא מבוטלת. כדי לרשום את מאזין האירועים, מבצעים את השלבים הבאים:
-
מבצעים קריאה ל-method
addEndListener()ומצרפים את ה-listener לאנימציה. -
אפשר לבטל את השיטה
onAnimationEnd()כדי לקבל התראה בכל פעם שאנימציה מגיעה לשיווי משקל או מבוטלת.
הסרת listeners
כדי להפסיק לקבל קריאות חוזרות לעדכון אנימציה וקריאות חוזרות לסיום אנימציה, צריך להפעיל את השיטות removeUpdateListener() ו-removeEndListener() בהתאמה.
הגדרת ערך התחלתי לאנימציה
כדי להגדיר את ערך ההתחלה של האנימציה, קוראים ל-method setStartValue() ומעבירים את ערך ההתחלה של האנימציה. אם לא מגדירים את ערך ההתחלה, האנימציה משתמשת בערך הנוכחי של מאפיין האובייקט כערך ההתחלה.
הגדרת טווח ערכי אנימציה
אפשר להגדיר את ערכי האנימציה המינימליים והמקסימליים כשרוצים להגביל את ערך המאפיין לטווח מסוים. הוא גם עוזר לשלוט בטווח במקרה של אנימציה של מאפיינים עם טווח פנימי, כמו אלפא (מ-0 עד 1).
-
כדי להגדיר את הערך המינימלי, קוראים לשיטה
setMinValue()ומעבירים את הערך המינימלי של המאפיין. -
כדי להגדיר את הערך המקסימלי, קוראים לשיטה
setMaxValue()ומעבירים את הערך המקסימלי של המאפיין.
שתי השיטות מחזירות את האנימציה שעבורה מוגדר הערך.
הערה: אם הגדרתם את ערך ההתחלה והגדרתם טווח ערכים לאנימציה, ודאו שערך ההתחלה נמצא בטווח הערכים המינימלי והמקסימלי.
הגדרת מהירות התחלתית
המהירות ההתחלתית מגדירה את המהירות שבה משתנה מאפיין האנימציה בתחילת האנימציה. מהירות ההתחלה שמוגדרת כברירת מחדל היא אפס פיקסלים לשנייה. אפשר להגדיר את המהירות באמצעות המהירות של תנועות המגע או באמצעות ערך קבוע כמהירות ההתחלתית. אם בוחרים לספק ערך קבוע, מומלץ להגדיר את הערך ב-dp לשנייה ואז להמיר אותו לפיקסלים לשנייה. הגדרת הערך ב-dp לשנייה מאפשרת שהמהירות לא תהיה תלויה בדחיסות ובגורמי צורה. למידע נוסף על המרת ערך לפיקסלים לשנייה, אפשר לעיין בקטע המרת DPI לשנייה לפיקסלים לשנייה.
כדי להגדיר את המהירות, קוראים ל-method
setStartVelocity()
ומעבירים את המהירות בפיקסלים לשנייה. השיטה מחזירה את
אובייקט כוח הקפיץ שעליו מוגדרת המהירות.
הערה: כדי לאחזר ולחשב את המהירות של מחוות מגע, משתמשים בשיטות של המחלקה GestureDetector.OnGestureListener או VelocityTracker.
Kotlin
findViewById<View>(R.id.imageView).also { img -> SpringAnimation(img, DynamicAnimation.TRANSLATION_Y).apply { … // Compute velocity in the unit pixel/second vt.computeCurrentVelocity(1000) val velocity = vt.yVelocity setStartVelocity(velocity) } }
Java
final View img = findViewById(R.id.imageView); final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y); … // Compute velocity in the unit pixel/second vt.computeCurrentVelocity(1000); float velocity = vt.getYVelocity(); anim.setStartVelocity(velocity);
המרת dp לשנייה לפיקסלים לשנייה
המהירות של קפיץ חייבת להיות בפיקסלים לשנייה. אם בוחרים לספק ערך קבוע כהתחלה של המהירות, צריך לספק את הערך ב-dp לשנייה ואז להמיר אותו לפיקסלים לשנייה. לצורך המרה, משתמשים בשיטה
applyDimension()
מהמחלקה TypedValue. כדאי לעיין בדוגמת הקוד הבאה:
Kotlin
val pixelPerSecond: Float = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpPerSecond, resources.displayMetrics)
Java
float pixelPerSecond = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpPerSecond, getResources().getDisplayMetrics());
הגדרת מאפייני אביב
במחלקה SpringForce מוגדרים getter ו-setter לכל אחד ממאפייני הקפיץ, כמו יחס שיכוך וקשיחות. כדי להגדיר את מאפייני הקפיץ, חשוב לאחזר את אובייקט כוח הקפיץ או ליצור כוח קפיץ בהתאמה אישית שבו אפשר להגדיר את המאפיינים. מידע נוסף על יצירת כוח קפיץ בהתאמה אישית זמין בקטע יצירת כוח קפיץ בהתאמה אישית.
הערה: כשמשתמשים בשיטות setter, אפשר ליצור שרשרת שיטות כי כל שיטות ה-setter מחזירות את אובייקט כוח הקפיץ.
יחס השיכוך
יחס השיכוך מתאר הפחתה הדרגתית בתנודה של קפיץ. בעזרת יחס השיכוך, אפשר להגדיר כמה מהר התנודות דועכות מניתור אחד לניתור הבא. יש ארבע דרכים שונות לשיכוך של קפיץ:
- ריסון יתר מתרחש כשמקדם הריסון גדול מאחד. היא מאפשרת לאובייקט לחזור בעדינות למצב המנוחה.
- שיכוך קריטי מתרחש כשמקדם השיכוך שווה לאחד. הוא מאפשר לאובייקט לחזור למצב המנוחה תוך פרק הזמן הקצר ביותר.
- שיכוך חלש מתרחש כשיחס השיכוך קטן מאחד. היא מאפשרת לאובייקט לעבור את מיקום המנוחה כמה פעמים, ואז להגיע אליו בהדרגה.
- ריסון לא יעיל מתרחש כשמקדם הריסון שווה לאפס. היא מאפשרת לאובייקט לנוע קדימה ואחורה ללא הפסקה.
כדי להוסיף את יחס השיכוך לקפיץ, פועלים לפי השלבים הבאים:
-
מבצעים קריאה ל-method
getSpring()כדי לאחזר את הקפיץ ולהוסיף את יחס השיכוך. -
מבצעים קריאה ל-method
setDampingRatio()ומעבירים את יחס השיכוך שרוצים להוסיף לקפיץ. השיטה מחזירה את אובייקט כוח הקפיץ שעליו מוגדר יחס השיכוך.הערה: יחס השיכוך חייב להיות מספר לא שלילי. אם מגדירים את מקדם השיכוך לאפס, הקפיץ לא יגיע לעולם למצב המנוחה. במילים אחרות, הוא מתנדנד לנצח.
המערכת כוללת את קבועי יחס השיכוך הבאים:
DAMPING_RATIO_HIGH_BOUNCYDAMPING_RATIO_MEDIUM_BOUNCYDAMPING_RATIO_LOW_BOUNCYDAMPING_RATIO_NO_BOUNCY
איור 2: שיעור יציאה גבוה
איור 3: שיעור נטישה בינוני
איור 4: שיעור נטישה נמוך
איור 5: אין החזרה
יחס השיכוך שמוגדר כברירת מחדל הוא DAMPING_RATIO_MEDIUM_BOUNCY.
Kotlin
findViewById<View>(R.id.imageView).also { img -> SpringAnimation(img, DynamicAnimation.TRANSLATION_Y).apply { … // Setting the damping ratio to create a low bouncing effect. spring.dampingRatio = SpringForce.DAMPING_RATIO_LOW_BOUNCY … } }
Java
final View img = findViewById(R.id.imageView); final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y); … // Setting the damping ratio to create a low bouncing effect. anim.getSpring().setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY); …
נוקשות
הפרמטר Stiffness (קשיחות) מגדיר את קבוע הקפיץ, שמודד את חוזק הקפיץ. קפיץ קשיח מפעיל יותר כוח על האובייקט שמחובר אליו כשהקפיץ לא נמצא במצב מנוחה. כדי להוסיף את הקשיחות לקפיץ, מבצעים את השלבים הבאים:
-
מבצעים קריאה ל-method
getSpring()כדי לאחזר את הקפיץ ולהוסיף את הקשיחות. -
מבצעים קריאה ל-method
setStiffness()ומעבירים את ערך הקשיחות שרוצים להוסיף לקפיץ. השיטה מחזירה את אובייקט כוח הקפיץ שעליו מוגדרת הקשיחות.הערה: הקשיחות חייבת להיות מספר חיובי.
המערכת כוללת את קבועי הקשיחות הבאים:
איור 6: קשיחות גבוהה
איור 7: נוקשות בינונית
איור 8: קשיחות נמוכה
איור 9: קשיחות נמוכה מאוד
ערך ברירת המחדל של הקשיחות הוא STIFFNESS_MEDIUM.
Kotlin
findViewById<View>(R.id.imageView).also { img -> SpringAnimation(img, DynamicAnimation.TRANSLATION_Y).apply { … // Setting the spring with a low stiffness. spring.stiffness = SpringForce.STIFFNESS_LOW … } }
Java
final View img = findViewById(R.id.imageView); final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y); … // Setting the spring with a low stiffness. anim.getSpring().setStiffness(SpringForce.STIFFNESS_LOW); …
יצירת כוח קפיץ בהתאמה אישית
אתם יכולים ליצור כוח קפיץ מותאם אישית במקום להשתמש בכוח הקפיץ שמוגדר כברירת מחדל. הכוח המותאם אישית של הקפיץ מאפשר לכם לשתף את אותו מופע של כוח הקפיץ בין כמה אנימציות של קפיץ. אחרי שיוצרים את כוח הקפיץ, אפשר להגדיר מאפיינים כמו יחס שיכוך וקשיחות.
-
יוצרים אובייקט
SpringForce.SpringForce force = new SpringForce(); -
מקצים את המאפיינים באמצעות קריאה לשיטות המתאימות. אפשר גם ליצור שרשור של שיטות.
force.setDampingRatio(DAMPING_RATIO_LOW_BOUNCY).setStiffness(STIFFNESS_LOW); -
מבצעים קריאה ל-
setSpring()כדי להגדיר את הקפיץ לאנימציה.setSpring(force);
הפעלת האנימציה
יש שתי דרכים להתחיל אנימציה של קפיץ: על ידי קריאה לשיטה start() או על ידי קריאה לשיטה animateToFinalPosition(). צריך להפעיל את שתי השיטות ב-thread הראשי.
השיטה animateToFinalPosition() מבצעת שתי משימות:
- מגדיר את המיקום הסופי של הקפיץ.
- מפעיל את האנימציה, אם היא לא הופעלה.
השיטה מעדכנת את המיקום הסופי של הקפיץ ומתחילה את האנימציה אם צריך, כך שאפשר לקרוא לשיטה הזו בכל שלב כדי לשנות את מהלך האנימציה. לדוגמה, באנימציית קפיץ בשרשרת, האנימציה של תצוגה אחת תלויה בתצוגה אחרת. במקרה של אנימציה כזו, נוח יותר להשתמש בשיטה animateToFinalPosition(). אם משתמשים בשיטה הזו באנימציית קפיץ משורשרת, לא צריך לדאוג אם האנימציה שרוצים לעדכן בהמשך פועלת כרגע.
איור 10 מציג אנימציה של קפיץ בשרשרת, שבה האנימציה של תצוגה אחת תלויה בתצוגה אחרת.
כדי להשתמש ב-method animateToFinalPosition(), מבצעים קריאה ל-method animateToFinalPosition() ומעבירים את מיקום המנוחה של הקפיץ. אפשר גם להגדיר את מצב המנוחה של הקפיץ באמצעות הפעלת השיטה setFinalPosition().
השיטה start() לא מגדירה את ערך המאפיין לערך ההתחלתי באופן מיידי. ערך המאפיין משתנה בכל פעימה של האנימציה, שמתרחשת לפני שלב הציור.
כתוצאה מכך, השינויים משתקפים בפריים הבא, כאילו הערכים נקבעו מיד.
Kotlin
findViewById<View>(R.id.imageView).also { img -> SpringAnimation(img, DynamicAnimation.TRANSLATION_Y).apply { … // Starting the animation start() … } }
Java
final View img = findViewById(R.id.imageView); final SpringAnimation anim = new SpringAnimation(img, DynamicAnimation.TRANSLATION_Y); … // Starting the animation anim.start(); …
ביטול האנימציה
אפשר לבטל את האנימציה או לדלג לסוף שלה. מצב אידיאלי שבו צריך לבטל את האנימציה או לדלג לסוף שלה הוא כשאינטראקציה של משתמש מחייבת את סיום האנימציה באופן מיידי. האירוע הזה מתרחש בעיקר כשמשתמש יוצא מאפליקציה באופן פתאומי או כשהתצוגה הופכת לבלתי נראית.
יש שתי שיטות שבהן אפשר להשתמש כדי להפסיק את האנימציה.
השיטה cancel() מסיימת את האנימציה בערך שבו היא נמצאת. השיטה skipToEnd() מדלגת על האנימציה לערך הסופי ואז מסיימת אותה.
לפני שמסיימים את האנימציה, חשוב קודם לבדוק את מצב הקפיץ. אם המצב של המדינה לא מרוסן, האנימציה לא יכולה להגיע למצב המנוחה.
כדי לבדוק את מצב הקפיץ, מבצעים קריאה לשיטה canSkipToEnd(). אם
הקפיץ מרוסן, הפונקציה מחזירה true, אחרת
false.
אחרי שמזהים את מצב הקפיץ, אפשר להפסיק את האנימציה באמצעות השיטה skipToEnd() או השיטה cancel(). צריך להפעיל את ה-method cancel() רק ב-thread הראשי.
הערה: בדרך כלל, השימוש בשיטה skipToEnd() גורם לקפיצה ויזואלית.