النقاط الرئيسية
Interpolator — واجهة في Android تقوم بتعيين القيمة الكسرية لتقدم الرسوم المتحركة (من 0.0 إلى 1.0) إلى قيمة فعلية بسرعة معدلة. إذا استمرت الرسوم المتحركة 300 مللي ثانية، يقوم النظام باستدعاء Interpolator لكل إطار، مرراً التقدم الحالي. يعيد Interpolator قيمة معدلة — على سبيل المثال، مع AccelerateInterpolator عند 50% من الوقت، تكون الرسوم المتحركة قد قطعت ~25% فقط من المسار، محاكية التسارع.
رياضياً، يمكن تمثيل Interpolator كدالة f(t)، حيث t هو الوقت المعياري [0, 1]، و f(t) هي القيمة المعيارية [0, 1] (أو أوسع لـ Overshoot/Bounce). يعيد LinearInterpolator f(t) = t — يتحرك الكائن بسرعة ثابتة. يقارب AccelerateInterpolator f(t) = t²، ويقارب DecelerateInterpolator f(t) = 1 − (1 − t)²، مما يخلق بداية أو نهاية سلسة. في Android Animation Framework، يتم تطبيق Interpolator على كل من ValueAnimator و ObjectAnimator و ViewPropertyAnimator، مما يوفر نهجاً موحداً للتحكم في السرعة على جميع المستويات.
يقدم Android 9 منحنيات استيفاء مدمجة، لكل منها نموذجها الرياضي الخاص. يحدد اختيار المنحنى طابع الرسوم المتحركة: الفيزيائية (Bounce)، المرونة (Overshoot) أو النعومة (AccelerateDecelerate).
| المنحنى | الرياضيات | حالة الاستخدام |
|---|---|---|
| LinearInterpolator | f(t) = t | مؤشرات التقدم، النص المتحرك |
| AccelerateInterpolator | f(t) = tⁿ (n=2) | عنصر يغادر الشاشة، يظهر من الأسفل |
| DecelerateInterpolator | f(t) = 1 − (1 − t)ⁿ | جسم يسقط، يدخل من الأعلى مع تباطؤ |
| AccelerateDecelerateInterpolator | تقريب cos | عام، ظهور/اختفاء العناصر |
| AnticipateInterpolator | تكعيبية مع تراجع | دخول نابض — يتراجع الجسم قليلاً قبل البدء |
| OvershootInterpolator | تكعيبية مع تجاوز | زر إجراء — يتجاوز قليلاً الموضع المستهدف |
| AnticipateOvershootInterpolator | مزيج من Anticipate + Overshoot | بطاقات — تراجع + تجاوز مع عودة |
| BounceInterpolator | ارتدادات مخمدة | كرة، عنصر يسقط على سطح |
| PathInterpolator | Bezier تكعيبية (نقطتي تحكم) | منحنيات مخصصة لنظام التصميم |
كل منحنى استيفاء له إعلان XML في res/interpolator/ وفئة Kotlin في حزمة android.view.animation. AccelerateDecelerateInterpolator هو الأكثر استخداماً: منحنيه يشبه دالة التسهيل ease-in-out في CSS. لتطبيقات Android مع Material Design، يُوصى باستخدام OvershootInterpolator لأزرار الإجراءات العائمة (FAB) — فهو يخلق تأثير "ارتداد" عند الظهور.
PathInterpolator — منحنى استيفاء يعتمد على منحنى Bezier، محدد عبر كائن Path. متاح منذ API 21 (Android 5.0). يسمح بتصميم منحنى السرعة بصرياً — يصمم المصمم المنحنى، وينقله المطور إلى الكود عبر إحداثيات نقاط التحكم. يتم دعم Bezier التكعيبية فقط (نقطتي تحكم C1، C2).
منحنى PathInterpolator يبدأ دائماً من النقطة (0,0) وينتهي عند (1,1). تحدد نقاط التحكم الشكل: (x1, y1) — نقطة البداية، (x2, y2) — نقطة النهاية. يجب أن تكون قيم x في النطاق [0,1] — وهذا يضمن الرتابة بمرور الوقت. يمكن أن تخرج قيم y عن [0,1] — وهذا يخلق تأثير تجاوز أو تراجع. على سبيل المثال، يستخدم Material Design القياسي منحنى fast-out-slow-in مع نقاط تحكم (0.4, 0.0, 0.2, 1.0). في IT Sectr نبني PathInterpolators مخصصة لكل نظام تصميم — وهذا يضمن اتساق الرسوم المتحركة عبر جميع الشاشات.
إذا لم تغطِ منحنيات الاستيفاء المدمجة السيناريو الخاص بك، يسمح Android بإنشاء منحنى مخصص عبر تطبيق واجهة TimeInterpolator. الطريقة الوحيدة هي getInterpolation(input: Float): Float. Input هو التقدم الحالي للرسوم المتحركة من 0 إلى 1؛ output هو القيمة المعدلة. يمكن أن يخرج output عن [0,1] لتأثيرات التجاوز أو الارتداد.
منحنيات الاستيفاء المخصصة النموذجية: تأثير ارتداد مخمد (يتجاوز 1.0 ويعود)، تأثير مرن (تخميد جيبي)، منحنى استيفاء متدرج (قفزات منفصلة). يمكن أيضاً تعريف منحنيات الاستيفاء المخصصة عبر XML باستخدام العلامة <interpolator> وتحديد الفئة. يحتوي Android Studio على معاينة مدمجة لـ Interpolator في Layout Inspector — تعرض المنحنى الفعلي للمنحنى المحدد، مما يبسط التصحيح.
رسوم متحركة أساسية لتكبير الزر باستخدام منحنى استيفاء متماثل. يغير ValueAnimator القيمة من 1.0 إلى 1.2 والعكس، ويجعل AccelerateDecelerateInterpolator الحركة سلسة.
import android.animation.ValueAnimator
import android.view.animation.AccelerateDecelerateInterpolator
import android.view.View
fun View.pulseAnimation() {
ValueAnimator.ofFloat(1.0f, 1.2f).apply {
duration = 300
interpolator = AccelerateDecelerateInterpolator()
repeatCount = 1
repeatMode = ValueAnimator.REVERSE
addUpdateListener { animator ->
val scale = animator.animatedValue as Float
this@pulseAnimation.scaleX = scale
this@pulseAnimation.scaleY = scale
}
start()
}
}
AccelerateDecelerateInterpolator يخلق تسارعاً سلساً في البداية وتباطؤاً سلساً في النهاية. يكرر وضع REVERSE الرسوم المتحركة في الاتجاه المعاكس، مما يخلق تأثير نبض. يُستخدم هذا النمط لأزرار الإجراءات، لجذب انتباه المستخدم إلى عنصر واجهة رئيسي.
منحنى مخصص مع تأثير تجاوز — يتجاوز الكائن الموضع المستهدف بنسبة 10% ويعود. تحدد نقاط التحكم (0.4, 0.0, 0.6, 1.3) دخولاً متسارعاً مع تجاوز.
import android.animation.ObjectAnimator
import android.graphics.Path
import android.view.animation.PathInterpolator
import android.view.View
fun View.slideWithOvershoot() {
val path = Path().apply {
cubicTo(0.4f, 0.0f, 0.6f, 1.3f, 1.0f, 1.0f)
}
val interpolator = PathInterpolator(path)
ObjectAnimator.ofFloat(this, "translationY", 200f, 0f).apply {
duration = 400
interpolator = interpolator
start()
}
}
PathInterpolator يقبل Path بمنحنى Bezier تكعيبي. في المثال، "يتجاوز" العنصر الموضع المستهدف (y=1.3 عند 60% من الوقت) ويعود إلى الموضع النهائي. يجب أن يكون Path رتيباً تماماً على طول المحور x، وإلا ستتحرك الرسوم المتحركة للخلف. للتحقق، استخدم Layout Inspector في Android Studio.
منحنى استيفاء مخصص مع تأثير ارتداد مخمد. تنفيذ عبر TimeInterpolator بأربع دورات تخميد.
import android.animation.TimeInterpolator
class DampedBounceInterpolator : TimeInterpolator {
private val cycles = 4
private val damping = 0.85f
override fun getInterpolation(input: Float): Float {
val t = input * cycles
val decay = Math.pow(damping.toDouble(), cycles.toDouble()).toFloat()
val peak = t - (Math.floor(t.toDouble())).toFloat()
val bounce = Math.sin(peak * Math.PI).toFloat()
return 1f - bounce * decay * (1f - input)
}
}
DampedBounceInterpolator المخصص يخلق 4 ارتدادات مخمدة بمعامل تخميد 0.85. تأخذ طريقة getInterpolation مدخلاً خطياً وتعيد قيمة بتأثير "نابض". في IT Sectr نستخدم منحنى الاستيفاء هذا لرسوم متحركة لظهور الإشعارات — يخلق الارتداد إحساساً بالفيزيائية ويجذب الانتباه.
الأسئلة الشائعة
AccelerateDecelerateInterpolator يخلق منحنى متماثل — يتسارع الكائن في البداية ويتباطأ في النهاية. يسمح PathInterpolator بتحديد منحنى عشوائي عبر Path بنقطة تحكم (Bezier تكعيبية). للرسوم المتحركة المخصصة ذات السلوك غير المتماثل (مثلاً، بداية سريعة + نهاية بطيئة)، استخدم PathInterpolator مع نقاط تحكم (0.2, 0.8, 0.4, 1.0).
نعم، قم بتطبيق واجهة TimeInterpolator وتجاوز طريقة getInterpolation(input: Float): Float. Input هو قيمة كسرية من 0 إلى 1 (تقدم الرسوم المتحركة)، output هو القيمة الفعلية. على سبيل المثال، يتم تنفيذ تأثير الارتداد بإرجاع قيم أكبر من 1 أو أقل من 0 لسلوك نابض. سجل منحنى الاستيفاء عبر علامة XML
تمت إضافة PathInterpolator في API 21 (Android 5.0 Lollipop). للإصدارات القديمة، استخدم AccelerateDecelerateInterpolator أو TimeInterpolator مخصص. يدعم PathInterpolator فقط منحنيات Bezier التكعيبية بنقطتي تحكم — الخطوط المستقيمة والمنحنيات التربيعية قد تعطي استيفاء غير صحيح. للتوافق مع الإصدارات السابقة، استخدم AccelerateDecelerateInterpolator كبديل.
يوصي Material Design 3 بمنحنى fast-out-slow-in بنقاط تحكم (0.4, 0.0, 0.2, 1.0) لظهور العناصر، linear-out-slow-in (0.0, 0.0, 0.2, 1.0) للاختفاء، fast-out-linear-in (0.4, 0.0, 1.0, 1.0) للحركة. في Android، هذه المنحنيات مطبقة في فئة FastOutSlowInInterpolator من مكتبة Material Components.
بأقل قدر. منحنيات الاستيفاء المدمجة تنفذ عملية رياضية واحدة لكل إطار — العبء غير ملحوظ. منحنيات الاستيفاء المخصصة ذات الحسابات الثقيلة (علم المثلثات، الحلقات) قد تسبب micro-jank على الأجهزة الضعيفة. قم بالتحسين عبر الحساب المسبق للقيم في المنشئ أو استخدم TimeInterpolator مع التخزين المؤقت.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا