تعتمد الحركة المستندة إلى الفيزياء على القوة. قوة النابض هي إحدى هذه القوى التي توجّه التفاعل والحركة. تتضمّن قوة النابض الخصائص التالية: التخميد والصلابة. في الصورة المتحركة المستندة إلى الزنبرك، يتم احتساب القيمة والسرعة استنادًا إلى قوة الزنبرك التي يتم تطبيقها على كل إطار.
إذا كنت تريد أن تتباطأ الرسوم المتحركة في تطبيقك في اتجاه واحد فقط، يمكنك استخدام رسوم متحركة مستندة إلى الاحتكاك بدلاً من ذلك.
مراحل نشاط التحريك الارتدادي
في الحركة المستندة إلى النوابض، يتيح لك الصف SpringForce
تخصيص صلابة النابض ونسبة التخميد والموضع النهائي. وبمجرد بدء الصورة المتحركة، تعدّل قوة النابض
قيمة الصورة المتحركة والسرعة في كل إطار. تستمر الحركة إلى أن تصل قوة النابض إلى حالة اتزان.
على سبيل المثال، إذا سحبت رمز تطبيق على الشاشة ثم تركته عن طريق رفع إصبعك عن الرمز، سيعود الرمز إلى مكانه الأصلي بفعل قوة غير مرئية ولكنها مألوفة.
يوضّح الشكل 1 تأثيرًا مشابهًا للنابض. تشير علامة الجمع (+) في منتصف الدائرة إلى القوة المطبَّقة من خلال إيماءة اللمس.
إنشاء تحريك ارتدادي
في ما يلي الخطوات العامة لإنشاء تحريك ارتدادي لتطبيقك:
- إضافة مكتبة الدعم يجب إضافة مكتبة الدعم إلى مشروعك لاستخدام فئات الصور المتحركة المستندة إلى الزنبرك.
- إنشاء تحريك ارتدادي:
الخطوة الأساسية هي إنشاء مثيل لفئة
SpringAnimationوضبط مَعلمات سلوك الحركة. - (اختياري) تسجيل أدوات معالجة الأحداث:
سجِّل أدوات معالجة الأحداث لتتبُّع التغييرات في مراحل نشاط الصورة المتحركة وتعديلات قيمتها.
ملاحظة: يجب تسجيل أداة معالجة التعديلات فقط إذا كنت بحاجة إلى تعديل كل إطار على حدة عند تغيير قيم الرسوم المتحركة. يمنع مستمع التحديث تشغيل الرسم المتحرك على سلسلة منفصلة.
- (اختياري) إزالة المستمعين: أزِل المستمعين الذين لم يعودوا قيد الاستخدام.
- (اختياري) ضبط قيمة البدء: يمكنك تخصيص قيمة بدء الحركة.
- (اختياري) ضبط نطاق القيم: اضبط نطاق قيم الحركة لتقييد القيم ضمن الحد الأدنى والأقصى للنطاق.
- (اختياري) ضبط سرعة البدء: اضبط سرعة البدء للحركة.
- (اختياري) ضبط خصائص النابض: اضبط نسبة التخميد والصلابة على النابض.
- (اختياري) إنشاء نابض مخصّص: يمكنك إنشاء نابض مخصّص في حال عدم نيتك استخدام النابض التلقائي أو إذا أردت استخدام نابض مشترك في جميع أنحاء الصورة المتحركة.
- بدء الحركة: لبدء الحركة الارتدادية
- (اختياري) إلغاء الحركة: يتم إلغاء الحركة في حال خروج المستخدم من التطبيق أو إذا أصبحت طريقة العرض غير مرئية.
تتناول الأقسام التالية الخطوات العامة لإنشاء صورة متحركة تستند إلى حركة نابض بالتفصيل.
إضافة مكتبة الدعم
لاستخدام مكتبة الدعم المستندة إلى الفيزياء، عليك إضافة مكتبة الدعم إلى مشروعك على النحو التالي:
- افتح ملف
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 في صفحة الإصدارات.
إنشاء صورة متحركة ارتدادية
تتيح لك الفئة 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.
تسجيل أدوات معالجة الأحداث
يوفّر الصف DynamicAnimation معالجَين للأحداث، هما OnAnimationUpdateListener وOnAnimationEndListener.
تستمع هذه المعالجات إلى التعديلات في الصورة المتحركة، مثلاً عند حدوث تغيير في قيمة الصورة المتحركة وعندما تنتهي الصورة المتحركة.
OnAnimationUpdateListener
عندما تريد تحريك عدّة طرق عرض لإنشاء صورة متحركة متسلسلة، يمكنك إعداد OnAnimationUpdateListener لتلقّي ردّ كلّما حدث تغيير في سمة طريقة العرض الحالية. يُعلم دالة الرجوع العرض الآخر بتعديل موضع النابض
استنادًا إلى التغيير الذي تم إجراؤه في سمة العرض الحالي. لتسجيل أداة معالجة الأحداث، اتّبِع الخطوات التالية:
-
استدعِ طريقة
addUpdateListener()وأرفِق أداة معالجة الأحداث بالصورة المتحركة.ملاحظة: يجب تسجيل أداة معالجة التعديل قبل بدء الحركة. ومع ذلك، يجب تسجيل أداة معالجة التعديل فقط إذا كنت بحاجة إلى تعديل كل إطار على حدة بشأن تغييرات قيمة الحركة. يمنع مستمع التحديث تشغيل الرسم المتحرك على سلسلة منفصلة.
-
يمكنك إلغاء طريقة
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
يُعلم بنهاية صورة متحركة. يمكنك إعداد أداة معالجة الأحداث لتلقّي
استدعاء كلما وصلت الصورة المتحركة إلى حالة التوازن أو تم إلغاؤها. لتسجيل المستمع، اتّبِع الخطوات التالية:
-
استدعِ طريقة
addEndListener()وأرفِق أداة معالجة الأحداث بالصورة المتحركة. -
يمكنك تجاهل طريقة
onAnimationEnd()لتلقّي إشعار كلما وصلت حركة إلى حالة الاتزان أو تم إلغاؤها.
إزالة المستمعين
لإيقاف تلقّي عمليات رد الاتصال الخاصة بتحديث الرسوم المتحركة وعمليات رد الاتصال الخاصة بنهاية الرسوم المتحركة، استخدِم الطريقتَين removeUpdateListener() وremoveEndListener() على التوالي.
ضبط قيمة بدء الصورة المتحركة
لضبط قيمة بدء الصورة المتحركة، استدعِ طريقة
setStartValue()
ومرِّر قيمة بدء الصورة المتحركة. إذا لم تضبط قيمة البداية، سيستخدم الرسم المتحرك القيمة الحالية لسمة العنصر كقيمة بداية.
ضبط نطاق قيم الصورة المتحركة
يمكنك ضبط الحدّ الأدنى والأقصى لقيم الحركة عندما تريد حصر قيمة السمة في نطاق معيّن. ويساعد ذلك أيضًا في التحكّم في النطاق في حال تحريك سمات لها نطاق أساسي، مثل الشفافية (من 0 إلى 1).
-
لضبط الحد الأدنى للقيمة، استدعِ الدالة
setMinValue()وامرر الحد الأدنى لقيمة السمة. -
لضبط القيمة القصوى، استدعِ طريقة
setMaxValue()ومرِّر القيمة القصوى للسمة.
تعرض كلتا الطريقتين الصورة المتحركة التي يتم ضبط القيمة لها.
ملاحظة: إذا كنت قد ضبطت قيمة البدء وحدّدت نطاق قيم للصور المتحركة، تأكَّد من أنّ قيمة البدء تقع ضمن نطاق الحد الأدنى والحد الأقصى للقيم.
ضبط السرعة المتجهة الابتدائية
تحدّد السرعة المتجهة الابتدائية السرعة التي تتغيّر بها سمة الحركة في بداية الحركة. يتم ضبط سرعة البدء التلقائية على صفر بكسل في الثانية. يمكنك ضبط السرعة إما باستخدام سرعة إيماءات اللمس أو باستخدام قيمة ثابتة كسرعة بداية. إذا اخترت تقديم قيمة ثابتة، ننصحك بتحديد القيمة بوحدات dp في الثانية ثم تحويلها إلى وحدات بكسل في الثانية. يسمح تحديد القيمة بوحدات dp في الثانية بأن تكون السرعة مستقلة عن الكثافة وعوامل الشكل. لمزيد من المعلومات حول تحويل القيمة إلى وحدات بكسل في الثانية، يُرجى الرجوع إلى القسم تحويل وحدات dp في الثانية إلى وحدات بكسل في الثانية.
لضبط السرعة، استدعِ طريقة
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 لكل سمة من سمات النابض، مثل نسبة التخميد والصلابة. لضبط خصائص النابض، من المهم إما استرداد عنصر قوة النابض أو إنشاء قوة نابض مخصّصة يمكنك ضبط الخصائص عليها. لمزيد من المعلومات حول إنشاء قوة نابض مخصّصة، راجِع القسم إنشاء قوة نابض مخصّصة.
ملاحظة: أثناء استخدام طرق تحديد القيمة، يمكنك إنشاء سلسلة طرق لأنّ جميع طرق تحديد القيمة تعرض عنصر قوة النابض.
نسبة التخميد
تصف نسبة التخميد انخفاضًا تدريجيًا في تذبذب نابض. باستخدام نسبة التخميد، يمكنك تحديد مدى سرعة انخفاض التذبذبات من ارتداد إلى آخر. هناك أربع طرق مختلفة لتخميد نابض:
- يحدث التخميد الزائد عندما تكون نسبة التخميد أكبر من واحد. ويتيح هذا الإجراء للكائن العودة بسلاسة إلى وضع الاستراحة.
- يحدث التخميد الحرج عندما تكون نسبة التخميد مساوية للواحد. ويتيح للكائن العودة إلى وضع الراحة في أقصر وقت ممكن.
- يحدث التخميد الناقص عندما تكون نسبة التخميد أقل من واحد. يتيح هذا النوع للعنصر تجاوز موضع الاستراحة عدة مرات، ثم الوصول تدريجيًا إلى موضع الاستراحة.
- يحدث التخميد غير المحدود عندما تكون نسبة التخميد مساوية للصفر. ويتيح للكائن التذبذب إلى الأبد.
لإضافة نسبة التخميد إلى النابض، اتّبِع الخطوات التالية:
-
استدعِ طريقة
getSpring()لاسترداد النابض لإضافة نسبة التخميد. -
استدعِ طريقة
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); …
التصلّب
تحدّد الصلابة ثابت النابض الذي يقيس قوة النابض. يطبّق النابض الصلب قوة أكبر على الجسم المتصل به عندما لا يكون النابض في وضع الراحة. لإضافة الصلابة إلى النابض، اتّبِع الخطوات التالية:
-
استدعِ طريقة
getSpring()لاسترداد الزنبرك المراد إضافة الصلابة إليه. -
استدعِ طريقة
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(). يجب استدعاء كلتا الطريقتين في سلسلة التعليمات الرئيسية.
animateToFinalPosition()
تنفِّذ الطريقة مهمتَين:
- تضبط هذه السمة الموضع النهائي للنابض.
- يبدأ الصورة المتحركة إذا لم تبدأ.
بما أنّ الطريقة تعدّل الموضع النهائي للنابض وتبدأ الرسوم المتحركة إذا لزم الأمر، يمكنك استدعاء هذه الطريقة في أي وقت لتغيير مسار الرسوم المتحركة. على سبيل المثال، في تحريك ارتدادي متسلسل، تعتمد حركة أحد العروض على عرض آخر. بالنسبة إلى هذا النوع من الصور المتحركة، من الأسهل استخدام طريقة animateToFinalPosition(). باستخدام هذه الطريقة في تحريك ارتدادي متسلسل، لن تحتاج إلى القلق بشأن ما إذا كان التحريك الارتدادي الذي تريد تعديله لاحقًا قيد التشغيل حاليًا.
يوضّح الشكل 10 تحريكًا ارتداديًا متسلسلًا، حيث يعتمد التحريك الارتدادي لأحد العروض على عرض آخر.
لاستخدام طريقة animateToFinalPosition()،
استدعِ طريقة
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(). يجب استدعاء طريقة cancel() فقط في سلسلة التعليمات الرئيسية.
ملاحظة: بشكل عام، تتسبّب الطريقة
skipToEnd() في حدوث
انتقال مرئي.