پویانمایی حرکت بااستفاده از فیزیک فنری

امتحان کردن روش «نوشتن»
‫Jetpack Compose جعبه‌ابزار واسط کاربر توصیه‌شده برای Android است. با نحوه استفاده از «پویانمایی‌ها» در «نوشتن» آشنا شوید.

حرکت مبتنی بر فیزیک با نیرو هدایت می‌شود. نیروی فنر یکی از این نیروها است که تعامل‌پذیری و حرکت را هدایت می‌کند. نیروی فنر دارای ویژگی‌های زیر است: میرایی و سختی. در پویانمایی فنری، مقدار و سرعت براساس نیروی فنری که در هر قاب اعمال می‌شود محاسبه می‌شود.

اگر می‌خواهید پویانمایی‌های برنامه‌تان فقط در یک جهت کند شود، به‌جای آن از پویانمایی پرتابی مبتنی بر اصطکاک استفاده کنید.

چرخه حیات پویانمایی فنری

در پویانمایی فنری، کلاس SpringForce به شما امکان می‌دهد سختی فنر، نسبت میرایی آن، و موقعیت نهایی آن را سفارشی‌سازی کنید. به‌محض شروع پویانمایی، نیروی فنر مقدار پویانمایی و سرعت را در هر قاب به‌روز می‌کند. پویانمایی تا زمانی که نیروی فنر به تعادل برسد ادامه می‌یابد.

برای مثال، اگر نماد برنامه‌ای را در صفحه بکشید و بعداً با برداشتن انگشت از روی نماد آن را رها کنید، نماد با نیرویی نامرئی اما آشنا به جای اصلی خود برمی‌گردد.

شکل ۱ اثر فنری مشابهی را نشان می‌دهد. علامت به‌علاوه (+) در وسط دایره نشان‌دهنده نیروی اعمال‌شده ازطریق اشاره لمسی است.

انتشار بهاری
شکل ۱. جلوه نسخه بهاری

ساختن پویانمایی فنری

مراحل کلی برای ساختن پویانمایی فنری برای برنامه‌تان به این صورت است: به این صورت است:

بخش‌های زیر مراحل کلی ساختن پویانمایی فنری را به‌طور مفصل توضیح می‌دهد.

افزودن کتابخانه پشتیبانی

برای استفاده از کتابخانه پشتیبانی مبتنی بر فیزیک، باید کتابخانه پشتیبانی را به پروژه خود به‌صورت زیر اضافه کنید:

  1. فایل build.gradle را برای واحد برنامه باز کنید.
  2. کتابخانه پشتیبانی را به بخش dependencies اضافه کنید.

    شیک

            dependencies {
                def dynamicanimation_version = '1.0.0'
                implementation "androidx.dynamicanimation:dynamicanimation:$dynamicanimation_version"
            }
            

    کاتلین

            dependencies {
                val dynamicanimation_version = "1.0.0"
                implementation("androidx.dynamicanimation:dynamicanimation:$dynamicanimation_version")
            }
            

    برای مشاهده نسخه‌های فعلی این کتابخانه، اطلاعات مربوط به «پویانمایی پویا» را در صفحه نسخه‌ها ببینید.

پویانمایی فنری بسازید

کلاس SpringAnimation به شما امکان می‌دهد پویانمایی فنری برای شیء ایجاد کنید. برای ساختن پویانمایی فنری، باید نمونه‌ای از کلاس SpringAnimation ایجاد کنید و شیء، دارایی شیء موردنظرتان برای پویانمایی، و موقعیت فنری نهایی اختیاری را که می‌خواهید پویانمایی در آنجا متوقف شود ارائه دهید.

توجه: در زمان ایجاد پویانمایی فنری، موقعیت نهایی فنر اختیاری است. هرچند، باید قبل‌از شروع پویانمایی تعریف شود.

کاتلین

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)
}

جاوا

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: نشان‌دهنده شفافیت آلفا در نما است. مقدار پیش‌فرض ۱ (کدر) است، و مقدار ۰ نشان‌دهنده شفافیت کامل (نامرئی) است.
  • 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: این‌ها ویژگی‌های ابزاری پایه برای توصیف مکان نهایی نما در ظرف آن هستند.

ثبت شنوندگان

کلاس DynamicAnimation دو شنونده ارائه می‌دهد: OnAnimationUpdateListener و OnAnimationEndListener. این شنوندگان به به‌روزرسانی‌های پویانمایی گوش می‌دهند، مثلاً وقتی مقدار پویانمایی تغییر می‌کند و وقتی پویانمایی به پایان می‌رسد.

OnAnimationUpdateListener

وقتی می‌خواهید چندین نما را پویانمایی کنید تا پویانمایی زنجیره‌ای ایجاد کنید، می‌توانید OnAnimationUpdateListener را تنظیم کنید تا هر بار که تغییری در دارایی نمای فعلی ایجاد می‌شود، یک تماس برگشتی دریافت کند. بازخوان به نمای دیگر اطلاع می‌دهد که موقعیت فنری خود را براساس تغییر ایجادشده در دارایی نمای فعلی به‌روز کند. برای ثبت شنونده، مراحل زیر را انجام دهید:

  1. متد addUpdateListener() را فراخوانی کنید و شنونده را به پویانمایی پیوست کنید.

    توجه: باید شنونده به‌روزرسانی را قبل‌از شروع پویانمایی ثبت کنید. بااین‌حال، شنونده به‌روزرسانی فقط باید زمانی ثبت شود که به به‌روزرسانی هر قاب در تغییرات مقدار پویانمایی نیاز داشته باشید. شنونده به‌روزرسانی از اجرای احتمالی پویانمایی در رشته‌ای جداگانه جلوگیری می‌کند.

  2. روش onAnimationUpdate() را ملغی کنید تا تماس‌گیرنده را از تغییر در شیء فعلی مطلع کنید. کد نمونه زیر استفاده کلی از OnAnimationUpdateListener را نشان می‌دهد.

کاتلین

// 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) }

جاوا

// 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 پایان پویانمایی را اعلام می‌کند. می‌توانید شنونده را طوری تنظیم کنید که هرگاه پویانمایی به تعادل رسید یا لغو شد، بازخوانی دریافت کند. برای ثبت شنونده، مراحل زیر را انجام دهید:

  1. متد addEndListener() را فراخوانی کنید و شنونده را به پویانمایی پیوست کنید.
  2. روش onAnimationEnd() را ملغی کنید تا هروقت پویانمایی به تعادل رسید یا لغو شد اعلان دریافت کنید.

برداشتن شنوندگان

برای توقف دریافت برگشت‌های تماس به‌روزرسانی پویانمایی و برگشت‌های تماس پایان پویانمایی، به‌ترتیب متدهای removeUpdateListener() و removeEndListener() را فراخوانی کنید.

تنظیم مقدار شروع پویانمایی

برای تنظیم مقدار شروع پویانمایی، setStartValue() متد را فراخوانی کنید و مقدار شروع پویانمایی را ارسال کنید. اگر مقدار شروع را تنظیم نکنید، پویانمایی از مقدار فعلی دارایی شیء به‌عنوان مقدار شروع استفاده می‌کند.

تنظیم محدوده مقدار پویانمایی

وقتی می‌خواهید مقدار دارایی را به محدوده خاصی محدود کنید، می‌توانید مقادیر کمینه و بیشینه پویانمایی را تنظیم کنید. همچنین به کنترل محدوده درصورتی‌که ویژگی‌هایی را پویانمایی کنید که دارای محدوده ذاتی هستند، مانند آلفا (از ۰ تا ۱)، کمک می‌کند.

  • برای تنظیم حداقل مقدار، setMinValue() متد را فراخوانی کنید و حداقل مقدار دارایی را ارسال کنید.
  • برای تنظیم مقدار بیشینه، روش setMaxValue() را فراخوانی کنید و مقدار بیشینه دارایی را ارسال کنید.

هر دو روش پویانمایی را که مقدار برای آن تنظیم می‌شود برمی‌گردانند.

توجه: اگر مقدار شروع را تنظیم کرده‌اید و محدوده مقدار پویانمایی را تعریف کرده‌اید، مطمئن شوید مقدار شروع در محدوده مقدار حداقل و حداکثر باشد.

تنظیم سرعت شروع

سرعت شروع، سرعت تغییر دارایی پویانمایی را در ابتدای پویانمایی تعریف می‌کند. سرعت شروع پیش‌فرض روی صفر پیکسل در ثانیه تنظیم شده است. می‌توانید سرعت را با سرعت اشاره‌های لمسی یا بااستفاده از مقدار ثابت به‌عنوان سرعت شروع تنظیم کنید. اگر انتخاب کنید که مقدار ثابتی ارائه دهید، توصیه می‌کنیم مقدار را در واحد dp در ثانیه تعریف کنید و سپس آن را به پیکسل در ثانیه تبدیل کنید. تعریف مقدار در واحد پیکسل مستقل از تراکم در ثانیه به سرعت اجازه می‌دهد مستقل از تراکم و عوامل شکل باشد. برای اطلاعات بیشتر درباره تبدیل مقدار به پیکسل در ثانیه، به بخش تبدیل dp در ثانیه به پیکسل در ثانیه مراجعه کنید.

برای تنظیم سرعت، setStartVelocity() روش را فراخوانی کنید و سرعت را برحسب پیکسل در ثانیه ارسال کنید. این روش شیء نیروی فنری را که سرعت روی آن تنظیم شده است برمی‌گرداند.

توجه: از روش‌های کلاس GestureDetector.OnGestureListener یا VelocityTracker برای بازیابی و محاسبه سرعت اشاره‌های لمسی استفاده کنید.

کاتلین

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)
    }
}

جاوا

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 استفاده کنید. به کد نمونه زیر مراجعه کنید:

کاتلین

val pixelPerSecond: Float =
    TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpPerSecond, resources.displayMetrics)

جاوا

float pixelPerSecond = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dpPerSecond, getResources().getDisplayMetrics());

تنظیم کردن دارایی‌های بهاری

کلاس SpringForce روش‌های دریافت‌کننده و تنظیم‌کننده را برای هریک از ویژگی‌های فنر، مثل نسبت میرایی و سختی، تعریف می‌کند. برای تنظیم خصوصیات فنر، مهم است که یا شیء نیروی فنر را بازیابی کنید یا نیروی فنر سفارشی ایجاد کنید که بتوانید خصوصیات را روی آن تنظیم کنید. برای اطلاعات بیشتر درباره ایجاد نیروی فنری سفارشی، به بخش ایجاد نیروی فنری سفارشی مراجعه کنید.

نکته: هنگام استفاده از روش‌های تنظیم‌کننده، می‌توانید زنجیره روش ایجاد کنید زیرا همه روش‌های تنظیم‌کننده شیء نیروی فنر را برمی‌گردانند.

نسبت میرایی

نسبت میرایی کاهش تدریجی در نوسان فنر را توصیف می‌کند. با استفاده از نسبت میرایی، می‌توانید تعریف کنید که نوسانات با چه سرعتی از یک جهش به جهش بعدی کاهش می‌یابند. چهار روش مختلف برای میرایی فنر وجود دارد:

  • وقتی نسبت میرایی بیشتر از یک باشد، میرایی بیش‌ازحد رخ می‌دهد. این ویژگی به شیء اجازه می‌دهد به‌آرامی به حالت استراحت برگردد.
  • میرایی بحرانی زمانی رخ می‌دهد که نسبت میرایی برابر با یک باشد. این ویژگی به شیء اجازه می‌دهد در کوتاه‌ترین زمان ممکن به حالت استراحت برگردد.
  • وقتی نسبت میرایی کمتر از یک باشد، میرایی ناکافی رخ می‌دهد. این ویژگی به شیء اجازه می‌دهد چندین بار با عبور از موقعیت استراحت، از آن فراتر برود، و سپس به‌تدریج به موقعیت استراحت برسد.
  • وقتی نسبت میرایی برابر با صفر باشد، میرایی‌نشده رخ می‌دهد. این کار باعث می‌شود شیء برای همیشه نوسان کند.

برای افزودن نسبت میرایی به فنر، مراحل زیر را انجام دهید:

  1. برای بازیابی فنر و افزودن نسبت میرایی، روش getSpring() را فراخوانی کنید.
  2. متد setDampingRatio() را فراخوانی کنید و نسبت میرایی موردنظرتان را به فنر اضافه کنید. این روش شیء نیروی فنری را برمی‌گرداند که نسبت میرایی روی آن تنظیم شده است.

    توجه: نسبت میرایی باید عددی غیرمنفی باشد. اگر نسبت میرایی را روی صفر تنظیم کنید، فنر هرگز به وضعیت استراحت نمی‌رسد. به‌عبارت دیگر، برای همیشه نوسان می‌کند.

ثابت‌های نسبت میرایی زیر در سیستم دردسترس است:

شکل ۲: واگشت بالا

شکل ۳: پرش متوسط

شکل ۴: جهش کم

شکل ۵: بدون واگشت

نسبت میرایی پیش‌فرض روی DAMPING_RATIO_MEDIUM_BOUNCY تنظیم شده است.

کاتلین

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
        …
    }
}

جاوا

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);
…

سفتی

«سفتی» ثابت فنر را تعریف می‌کند که قدرت فنر را اندازه‌گیری می‌کند. وقتی فنر در وضعیت استراحت نباشد، فنر سفت نیروی بیشتری به جسم متصل وارد می‌کند. برای افزودن سختی به فنر، مراحل زیر را انجام دهید:

  1. برای بازیابی فنر و افزودن سختی، روش getSpring() را فراخوانی کنید.
  2. متد setStiffness() را فراخوانی کنید و مقدار سختی موردنظرتان را برای افزودن به فنر ارسال کنید. این روش شیء نیروی فنری را برمی‌گرداند که سفتی روی آن تنظیم شده است.

    توجه: سختی باید عدد مثبتی باشد.

ثابت‌های سختی زیر در سیستم دردسترس است:

شکل ۶: سفتی زیاد

شکل ۷: سفتی متوسط

شکل ۸: سفتی کم

شکل ۹: سفتی بسیار کم

سفتی پیش‌فرض روی STIFFNESS_MEDIUM تنظیم شده است.

کاتلین

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
        …
    }
}

جاوا

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);
…

ایجاد نیروی فنری سفارشی

می‌توانید نیروی فنری سفارشی را به‌عنوان جایگزینی برای استفاده از نیروی فنری پیش‌فرض ایجاد کنید. نیروی فنری سفارشی به شما امکان می‌دهد نمونه نیروی فنری یکسانی را در چندین پویانمایی فنری هم‌رسانی کنید. پس‌از ایجاد نیروی فنر، می‌توانید ویژگی‌هایی مثل نسبت میرایی و سختی را تنظیم کنید.

  1. یک شیء SpringForce ایجاد کنید.

    SpringForce force = new SpringForce();

  2. با فراخوانی روش‌های مربوطه، ویژگی‌ها را اختصاص دهید. همچنین می‌توانید زنجیره روش ایجاد کنید.

    force.setDampingRatio(DAMPING_RATIO_LOW_BOUNCY).setStiffness(STIFFNESS_LOW);

  3. برای تنظیم فنر برای پویانمایی، روش setSpring() را فراخوانی کنید.

    setSpring(force);

شروع کردن پویانمایی

به دو روش می‌توانید پویانمایی فنری را شروع کنید: با فراخوانی start() یا با فراخوانی animateToFinalPosition() متد. هر دو روش باید در رشته اصلی فراخوانی شوند.

animateToFinalPosition() روش دو تکلیف را انجام می‌دهد:

  • موقعیت نهایی فنر را تنظیم می‌کند.
  • اگر پویانمایی شروع نشده باشد، آن را شروع می‌کند.

ازآنجایی‌که این روش موقعیت نهایی فنر را به‌روز می‌کند و درصورت نیاز پویانمایی را شروع می‌کند، می‌توانید هرزمان خواستید این روش را برای تغییر دادن مسیر پویانمایی فراخوانی کنید. برای مثال، در پویانمایی فنری زنجیره‌ای، پویانمایی یک نما به نمای دیگر بستگی دارد. برای چنین پویانمایی، استفاده از animateToFinalPosition() روش راحت‌تر است. بااستفاده از این روش در پویانمایی فنری زنجیره‌ای، لازم نیست نگران باشید که آیا پویانمایی‌ای که می‌خواهید بعداً به‌روز کنید درحال اجرا است یا نه.

شکل ۱۰ پویانمایی فنری زنجیره‌ای را نشان می‌دهد که در آن پویانمایی یک نما به نمای دیگر بستگی دارد.

نسخه نمایشی چشمه داغ زنجیره‌ای
شکل ۱۰. نمونه نمایشی زنجیره‌ای فنر

برای استفاده از روش animateToFinalPosition() ، روش animateToFinalPosition() را فراخوانی کنید و موقعیت استراحت فنر را ارسال کنید. همچنین می‌توانید با فراخوانی روش، موقعیت استراحت فنر را تنظیم کنید. setFinalPosition() .

متد start() مقدار دارایی را بلافاصله روی مقدار شروع تنظیم نمی‌کند. مقدار ویژگی در هر ضربان پویانمایی تغییر می‌کند، که قبل‌از گذر طراحی اتفاق می‌افتد. درنتیجه، تغییرات در قاب بعدی منعکس می‌شود، انگار که مقادیر بلافاصله تنظیم شده‌اند.

کاتلین

findViewById<View>(R.id.imageView).also { img ->
    SpringAnimation(img, DynamicAnimation.TRANSLATION_Y).apply {
        …
        // Starting the animation
        start()
        …
    }
}

جاوا

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() باعث پرش دیداری می‌شود.