Property Animation: ما هو، ObjectAnimator وValueAnimator

المؤلف: IT Sectr نُشر: 2026-02-28 وقت القراءة: 10 دق

Property Animation هو نظام تحريك في Android، تم تقديمه في Android 3.0 (API 11)، والذي يغير الخصائص الحقيقية للكائنات (وليس View فقط) خلال فترة زمنية محددة. على عكس View Animation القديمة، يغير Property Animation الحقول الفعلية للكائن — الإحداثيات، الحجم، الشفافية، اللون — وليس فقط المظهر المرئي. وفقًا لـ Google Android Developers (2026)، يُستخدم Property Animation في 89% من تطبيقات Android من أفضل 100. اقرأ المزيد عن أنواع التحريك الأخرى في الدليل العام للتحريك.

أهم النقاط

  • Property Animation — نظام تحريك في Android لتغيير خصائص الكائنات عبر Animator.
  • ObjectAnimator — الفئة الرئيسية لتحريك خاصية محددة لكائن بقيم محددة.
  • ValueAnimator — الفئة الأساسية التي تولد قيمًا متحركة دون الارتباط بكائن معين.
  • AnimatorSet — يتيح دمج عدة محركات في تسلسل أو مجموعة متوازية.
  • يدعم Property Animation Interpolator وTypeEvaluator والاستماع عبر AnimatorListener.

ما هو Property Animation؟

Property Animation هو إطار عمل في Android SDK (حزمة android.animation) يقوم بتحريك أي خصائص لأي كائن (View، Drawable، فئة مخصصة) خلال وقت محدد. على عكس View Animation التي تعمل فقط مع View وتغير فقط التمثيل المرئي (تحويل المصفوفة)، يغير Property Animation الحقول الحقيقية للكائن. هذا يعني أنه بعد تحريك translationX، يكون الكائن فعليًا في الموضع الجديد، ويتم معالجة النقرات في الموقع الجديد.

تم بناء بنية Property Animation على ثلاث فئات رئيسية: ValueAnimator — المولد الأساسي للقيم، ObjectAnimator — فئة فرعية للربط بخاصية كائن، AnimatorSet — منسق للتحريك الجماعي. الثلاثة تدعم Interpolator (منحنى السرعة) وTypeEvaluator (قاعدة الاستيفاء بين القيم).

وفقًا لـ Android Performance Patterns (Google، 2025)، يعمل Property Animation حتى 60 إطارًا في الثانية مع Interpolator مضبوط بشكل صحيح وعدم وجود حسابات ثقيلة في onAnimationUpdate(). للتحريكات المعقدة (ثلاثية الأبعاد، الفيزياء)، يُوصى باستخدام RenderThread (RenderNode Animations) في Android 12+. يظل Property Animation الخيار الرئيسي لتحريك خصائص View — translationX وrotationY وscaleX وalpha وغيرها.

ObjectAnimator: تحريك خصائص الكائن

ObjectAnimator هو الفئة الأكثر شيوعًا في Property Animation. يمتد من ValueAnimator ويستدعي تلقائيًا setter الخاصية المحددة للكائن بقيم متحركة. لكي يعمل ObjectAnimator، يجب أن يكون للكائن setter عام للخاصية التي يتم تحريكها (مثل setTranslationX(float) لخاصية "translationX").

kotlin
import android.animation.ObjectAnimator
import android.view.View

// ObjectAnimator لـ translationX
val animator = ObjectAnimator.ofFloat(
    myView,
    "translationX",
    0f,
    300f
).apply {
    duration = 500L
    startDelay = 200L
    repeatCount = 1
    repeatMode = ValueAnimator.REVERSE
    interpolator = FastOutSlowInInterpolator()
    start()
}

خصائص View المدعومة: translationX، translationY، translationZ، rotation، rotationX، rotationY، scaleX، scaleY، alpha، x، y، elevation. يُستخدم ObjectAnimator.ofFloat() للخصائص العائمة، ofInt() للعدد الصحيح، ofObject() للأنواع المخصصة (لون، نقطة). لتحريك الألوان، استخدم ofObject() مع ArgbEvaluator أو HsvEvaluator.

kotlin
// ObjectAnimator مع TypeEvaluator مخصص (لون)
import android.animation.ObjectAnimator
import android.animation.ArgbEvaluator
import android.graphics.Color

val colorAnim = ObjectAnimator.ofObject(
    myView,
    "backgroundColor",
    ArgbEvaluator(),
    Color.BLUE,
    Color.RED
).apply {
    duration = 1000L
    repeatCount = ValueAnimator.INFINITE
    repeatMode = ValueAnimator.REVERSE
    start()
}

// تحريك عدة خصائص في وقت واحد
val scaleXAnim = ObjectAnimator.ofFloat(myView, "scaleX", 1f, 1.5f)
val scaleYAnim = ObjectAnimator.ofFloat(myView, "scaleY", 1f, 1.5f)
val alphaAnim = ObjectAnimator.ofFloat(myView, "alpha", 1f, 0.5f)

AnimatorListener — واجهة لتتبع أحداث التحريك: onAnimationStart، onAnimationEnd، onAnimationCancel، onAnimationRepeat. استخدم AnimatorListenerAdapter لتجاوز الطرق المطلوبة فقط. بدءًا من Android 12، تمت إضافة Animator.AnimationCallback مع دعم coroutines عبر suspendAnimationFrame.

ValueAnimator: توليد القيم المتحركة

ValueAnimator هو الفئة الأساسية لـ Property Animation التي تولد قيمًا متحركة من البداية إلى النهاية خلال وقت محدد. على عكس ObjectAnimator، ValueAnimator غير مرتبط بكائن — فهو ببساطة يحسب القيم الوسيطة ويُبلغ عبر مستمع. يقرر المطور ما يفعله بالقيم التي تم الحصول عليها: تعيين خاصية View، تغيير معلمة Drawable، تحديث الرسم المخصص في onDraw().

kotlin
import android.animation.ValueAnimator
import android.view.animation.LinearInterpolator

"> ValueAnimator: حركة تقدم التحميل
val valueAnimator = ValueAnimator.ofFloat(0f, 100f).apply {
    duration = 2000L
    interpolator = LinearInterpolator()
    repeatCount = ValueAnimator.INFINITE

    addUpdateListener { animator ->
        val progress = animator.animatedValue as Float
        progressBar.progress = progress.toInt()
        progressText.text = "${progress.toInt()}%"
    }

    addListener(object : AnimatorListenerAdapter() {
        override fun onAnimationRepeat(animation: Animator) {
            Log.d("Anim", "Progress animation restarted")
        }
    })
    start()
}

ValueAnimator.ofInt() — يُستخدم للخصائص الصحيحة (العرض، الارتفاع، عدد الخطوات). ValueAnimator.ofObject() — للأنواع المخصصة مع TypeEvaluator. ValueAnimator.ofPropertyValuesHolder() — للتحريك المتوازي لعدة خصائص بمؤقت واحد، مما يوفر الموارد مقارنةً بـ Animators منفصلة لكل خاصية.

kotlin
// ValueAnimator.ofObject مع PointEvaluator
import android.animation.ValueAnimator
import android.graphics.PointF
import android.animation.PointFEvaluator

val pointAnim = ValueAnimator.ofObject(
    PointFEvaluator(),
    PointF(0f, 0f),
    PointF(300f, 500f)
).apply {
    duration = 1000L
    addUpdateListener { animator ->
        val point = animator.animatedValue as PointF
        movingView.x = point.x
        movingView.y = point.y
    }
    start()
}

أداء ValueAnimator: عند 60 إطارًا في الثانية، يتم استدعاء onAnimationUpdate كل ~16.7 مللي ثانية. تجنب داخل المستمع: تخصيص الكائنات (أنشئ PointF/RectF مرة واحدة)، استدعاء findViewById()، الحسابات الثقيلة (إدخال/إخراج الملفات، الشبكة). لتحريك 20+ عنصرًا في وقت واحد، استخدم PropertyValuesHolder في Animator واحد بدلاً من 20 Animator منفصلة. للتحريك مع تغيير الحجم، استخدم View.setLayoutParams() فقط في نهاية التحريك (عبر AnimatorListenerAdapter.onAnimationEnd).

AnimatorSet: تركيب التحريكات

AnimatorSet هو منسق يتيح تشغيل عدة مثيلات Animator (ObjectAnimator، ValueAnimator) بترتيب محدد: بالتسلسل (playSequentially)، بالتوازي (playTogether)، مع تأخيرات (after، before، with). يدعم AnimatorSet التداخل — يمكن أن يحتوي AnimatorSet على AnimatorSets أخرى لسيناريوهات معقدة.

kotlin
import android.animation.AnimatorSet
import android.animation.ObjectAnimator

// AnimatorSet: تحريك تسلسلي ومتوازي
val fadeIn = ObjectAnimator.ofFloat(myView, "alpha", 0f, 1f)
val slideUp = ObjectAnimator.ofFloat(myView, "translationY", 100f, 0f)
val bounce = ObjectAnimator.ofFloat(myView, "scaleX", 1f, 1.1f, 1f)

val animatorSet = AnimatorSet().apply {
    // بالتوازي: fadeIn + slideUp
    play(fadeIn).with(slideUp)
    "> بعد: bounce مع تأخير 200ms
    play(bounce).after(200L)

    duration = 400L
    interpolator = FastOutSlowInInterpolator()
    addListener(object : AnimatorListenerAdapter() {
        override fun onAnimationEnd(animation: Animator) {
            Log.d("Anim", "Set completed")
        }
    })
    start()
}

AnimatorSet.Builder يوفر واجهة برمجة سلسة لبناء السلاسل: with() — بالتوازي، before() — قبل، after() — بعد. يدعم AnimatorSet cancel() لإيقاف جميع التحريكات في المجموعة. للسيناريوهات المعقدة (25+ محركًا)، استخدم PropertyValuesHolder — فهو أكثر كفاءة لأنه يستخدم مؤقتًا مشتركًا واحدًا بدلاً من مؤقت منفصل لكل Animator.

طريقة Builderالوصفمثال
with(Animator)تشغيل بالتوازي مع التحريك الحاليplay(fadeIn).with(slideUp)
before(Animator)التحريك الحالي قبل المحددplay(fadeIn).before(bounce)
after(Animator)التحريك الحالي بعد المحددplay(bounce).after(slideUp)
after(Long)تأخير قبل التحريك الحاليplay(bounce).after(200L)

Interpolator وTypeEvaluator: التحكم في السرعة والنوع

Interpolator يحدد منحنى سرعة التحريك من 0 إلى 1. يوفر Android Interpolators مدمجة: LinearInterpolator (منتظم)، AccelerateDecelerateInterpolator (بطيء-سريع-بطيء)، FastOutSlowInInterpolator (Material Design)، OvershootInterpolator (مع تجاوز الهدف)، BounceInterpolator (مع ارتداد)، AnticipateOvershootInterpolator (مع تراجع قبل البداية وتجاوز الهدف). يتم تنفيذ Interpolator مخصص عبر TimeInterpolator.

kotlin
import android.animation.ObjectAnimator
import android.view.animation.BounceInterpolator
import android.view.animation.OvershootInterpolator
import android.view.animation.AnticipateOvershootInterpolator

// BounceInterpolator — تأثير الارتداد في النهاية
val bounceAnim = ObjectAnimator.ofFloat(myView, "translationY", 0f, -50f).apply {
    duration = 600L
    interpolator = BounceInterpolator()
    start()
}

// AnticipateOvershoot — تراجع للخلف، ثم تجاوز
val anticipateAnim = ObjectAnimator.ofFloat(myView, "scaleX", 1f, 1.3f).apply {
    duration = 500L
    interpolator = AnticipateOvershootInterpolator(2.0f)
    start()
}

TypeEvaluator — واجهة بطريقة evaluate(fraction, startValue, endValue) تحسب القيمة الوسيطة بين البداية والنهاية. المدمجة: ArgbEvaluator (لون int)، FloatEvaluator، IntEvaluator، PointFEvaluator، RectEvaluator. لأنواع البيانات المخصصة (مثل تحريك فئة مخصصة بثلاثة حقول)، قم بتنفيذ TypeEvaluator الخاص بك. لتحريك عدة Views بنفس الإعدادات، استخدم PropertyValuesHolder — يقبل مصفوفة من أسماء الخصائص والقيم المقابلة.

kotlin
// TypeEvaluator مخصص لفئة ProgressState
data class ProgressState(val progress: Float, val color: Int)

class ProgressEvaluator : TypeEvaluator<ProgressState> {
    override fun evaluate(
        fraction: Float,
        startValue: ProgressState,
        endValue: ProgressState
    ): ProgressState {
        val progress = startValue.progress + fraction * (endValue.progress - startValue.progress)
        val color = ArgbEvaluator().evaluate(
            fraction, startValue.color, endValue.color
        ) as Int
        return ProgressState(progress, color)
    }
}

"> PropertyValuesHolder — أقصى أداء
val pvh1 = PropertyValuesHolder.ofFloat("scaleX", 1f, 1.5f)
val pvh2 = PropertyValuesHolder.ofFloat("scaleY", 1f, 1.5f)
val pvhAnim = ObjectAnimator.ofPropertyValuesHolder(myView, pvh1, pvh2).apply {
    duration = 300L
    start()
}

الأسئلة الشائعة

كيف يختلف Property Animation عن View Animation؟

View Animation (Tween Animation) يغير فقط التمثيل المرئي لـ View من خلال تحويل المصفوفة، دون التأثير على الخصائص الحقيقية للكائن. بعد تحريك translationX في View Animation، يتم إزاحة العنصر بصريًا، ولكن لا تزال النقرات تُعالج في الموضع الأصلي. Property Animation (ObjectAnimator) يغير الخاصية الحقيقية — بعد التحريك، يكون العنصر فعليًا في الموضع الجديد.

كيفية إيقاف Property Animation؟

استدع animator.cancel() — يتوقف التحريك فورًا، ولا يتم تطبيق القيمة النهائية. استدعاء animator.end() — ينتقل التحريك إلى الحالة النهائية ويتوقف. لـ AnimatorSet — set.cancel() يوقف جميع التحريكات في المجموعة. Animator.pause() وresume() متاحان على API 19+ للإيقاف المؤقت.

أي Interpolator يُستخدم لأنواع مختلفة من التحريك؟

يوصي Material Design: FastOutSlowInInterpolator — لتحريكات ظهور واختفاء العناصر، LinearInterpolator — لمؤشرات التحميل، OvershootInterpolator — للتأثيرات البارزة (الأزرار)، BounceInterpolator — للسحب للتحديث والعناصر النابضة. للتحريكات التي تظهر من خارج الشاشة، استخدم AccelerateDecelerateInterpolator.

لماذا لا يقوم ObjectAnimator بتحريك الخاصية؟

تحقق من: (1) الكائن لديه setter عام للخاصية المحددة (setPropertyName())، (2) الخاصية مكتوبة بـ camelCase بحرف صغير بعد "set"، (3) setter يقبل نفس النوع الذي تمرره (ofFloat → setPropertyName(float)). لـ View، جميع الخصائص القياسية (alpha، translationX، rotation، إلخ) لها setters.

متى تستخدم ObjectAnimator بدلاً من ValueAnimator؟

ObjectAnimator — عندما تقوم بتحريك خاصية View قياسية واحدة (alpha، translationX، rotation). ValueAnimator — عندما تحتاج إلى تحديث عدة خصائص من مستمع واحد، أو تحريك خصائص غير View (التقدم، الرسم المخصص)، أو عندما لا يحتوي الكائن على setter للخاصية المطلوبة. ValueAnimator أكثر مرونة ولكنه يتطلب المزيد من الكود للتحديثات اليدوية.

الملخص

  • Property Animation — إطار عمل Android لتحريك الخصائص الحقيقية للكائنات عبر Animator.
  • ObjectAnimator — تحريك خاصية محددة لكائن بقيم بداية/نهاية محددة.
  • ValueAnimator — توليد قيم متحركة مع تحديثات يدوية في onAnimationUpdate.
  • AnimatorSet — تنسيق عدة محركات تحريك بالتسلسل أو بالتوازي.
  • Interpolator — منحنى السرعة: FastOutSlowIn وLinear وBounce وOvershoot ومخصص.
  • TypeEvaluator — قاعدة الاستيفاء بين القيم لأنواع البيانات المخصصة.
  • Property Values Holder (PropertyValuesHolder) — تحسين للتحريك المتوازي لعدة خصائص.

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا