نکات اصلی
Interpolator — واسطی در Android است که مقدار کسری پیشرفت انیمیشن (از 0.0 تا 1.0) را به مقدار واقعی با سرعت تغییر یافته نگاشت میکند. اگر انیمیشن 300 میلیثانیه طول بکشد، سیستم برای هر فریم Interpolator را فراخوانی میکند و پیشرفت فعلی را ارسال میکند. Interpolator مقدار اصلاحشده را برمیگرداند — مثلاً برای AccelerateInterpolator در 50٪ زمان، انیمیشن تنها ~25٪ مسیر را طی میکند و شتاب را شبیهسازی میکند.
از نظر ریاضی، Interpolator را میتوان بهعنوان تابع f(t) نشان داد، جایی که t زمان نرمالشده [0, 1] و f(t) مقدار نرمالشده [0, 1] (یا گستردهتر برای Overshoot/Bounce) است. درونیاب خطی 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 مکعبی (2 نقطه کنترل) | منحنیهای سفارشی برای سیستم طراحی |
هر درونیاب یک اعلامیه XML در res/interpolator/ و یک کلاس Kotlin در بسته android.view.animation دارد. AccelerateDecelerateInterpolator — پرکاربردترین: منحنی آن شبیه تابع easing ease-in-out در CSS است. برای برنامههای Android با Material Design، OvershootInterpolator برای دکمههای floating action button (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] خارج شوند — این اثر عبور (overshoot) یا عقبکشیدن (anticipate) را ایجاد میکند. برای مثال، Material Design استاندارد از منحنی fast-out-slow-in با نقاط کنترل (0.4, 0.0, 0.2, 1.0) استفاده میکند. در IT Sectr برای هر سیستم طراحی PathInterpolator سفارشی میسازیم — این یکنواختی انیمیشنها را در همه صفحهها تضمین میکند.
اگر درونیابهای داخلی سناریو را پوشش نمیدهند، Android با پیادهسازی رابط TimeInterpolator امکان ایجاد درونیاب شخصی را فراهم میکند. تنها متد — getInterpolation(input: Float): Float. Input — پیشرفت فعلی انیمیشن از 0 تا 1؛ output — مقدار اصلاحشده. output میتواند برای اثرات عبور یا جهش از [0,1] خارج شود.
درونیابهای سفارشی معمول: اثر bounce با میرایی (خروج از 1.0 و بازگشت)، اثر elastic (میرایی سینوسی)، step-interpolator (جهشهای گسسته). درونیابهای سفارشی را میتوان از طریق 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 انیمیشن را در جهت معکوس تکرار میکند و اثر ضربان ایجاد میکند. این الگو برای دکمههای اقدام استفاده میشود و توجه کاربر را به عنصر کلیدی رابط جلب میکند.
منحنی سفارشی با اثر overshoot — شیء 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 — مقدار واقعی. برای مثال، اثر bounce با بازگرداندن مقادیر بزرگتر از 1 یا کوچکتر از 0 برای رفتار فنری پیادهسازی میشود. درونیاب را از طریق تگ XML
PathInterpolator در API 21 (Android 5.0 Lollipop) اضافه شده است. برای نسخههای قدیمیتر از AccelerateDecelerateInterpolator یا TimeInterpolator سفارشی استفاده کنید. PathInterpolator فقط منحنیهای Bezier مکعبی با دو نقطه کنترل را پشتیبانی میکند — خطوط مستقیم و منحنیهای درجه دوم ممکن است درونیابی نادرست ایجاد کنند. برای سازگاری عقبگرد از AccelerateDecelerateInterpolator بهعنوان fallback استفاده کنید.
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 از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید