نظرة عامة على الصور المتحركة للموقع

تجربة طريقة ComposeAllowed
Jetpack Compose هي مجموعة أدوات واجهة المستخدم التي ننصح بها لنظام التشغيل Android. تعرَّف على كيفية استخدام الصور المتحركة في ميزة "الكتابة".

نظام الصور المتحركة في الموقع هو إطار عمل قوي يتيح لك إضافة صور متحركة إلى أي عنصر تقريبًا. يمكنك تحديد رسم متحرك لتغيير أي خاصية كائن بمرور الوقت، بغض النظر عما إذا كان يجذب الشاشة أم لا. تغيّر الصورة المتحركة للخصائص (حقل في كائن) خلال مدة زمنية محددة. لإضافة تأثيرات متحركة إلى عنصر معيّن، حدِّد سمة العنصر التي تريد إضافة تأثيرات متحركة إليها، مثل موضع العنصر على الشاشة ومدّة إضافة تأثيرات متحركة إليه والقيم التي تريد إضافة تأثيرات متحركة إليها.

يتيح لك نظام الرسوم المتحركة للخصائص تحديد الخصائص التالية الرسوم المتحركة:

  • المدة: يمكنك تحديد مدة الصورة المتحركة. المدة التلقائية هي 300 ملي ثانية.
  • الاستقراء الزمني: يمكنك تحديد كيفية احتساب قيم السمة كأحد دوالّ الوقت المنقضي الحالي للحركة.
  • عدد التكرارات والسلوكيات: يمكنك تحديد ما إذا كان سيتم تكرار الرسم المتحرك أم لا عند يصل إلى نهاية المدة وعدد مرات تكرار الرسم المتحرك. يمكنك أيضًا تحديد ما إذا كنت تريد تشغيل الصورة المتحرّكة بشكل عكسي. الضبط على وضع التشغيل العكسي الحركة للأمام ثم للخلف بشكل متكرر، حتى يتم الوصول إلى عدد التكرارات.
  • مجموعات الصور المتحركة: يمكنك تجميع الرسوم المتحركة في مجموعات منطقية تعمل معًا أو بشكل تسلسلي أو بعد تأخيرات محددة.
  • تأخير تحديث الإطار: يمكنك تحديد عدد مرات تحديث إطارات الصورة المتحركة. يتم ضبط الإعداد تلقائيًا على إعادة التحميل كل 10 مللي ثانية، ولكن السرعة التي يمكن للتطبيق بها إعادة تحميل اللقطات تعتمد في النهاية على مدى انشغال النظام بشكل عام ومدى سرعة معالجة النظام للموقّت الأساسي.

للاطّلاع على مثال كامل للرسم المتحرك للخصائص، راجع صف واحد (ChangeColor) في النقل المخصص عينة على جيت هب.

آلية عمل الصورة المتحركة للخصائص

أولاً، لنستعرض كيفية عمل الرسوم المتحركة باستخدام مثال بسيط. يصور الشكل 1 كائن افتراضي يتضمّن صورة متحركة لسمته x التي تمثِّل الموقع الأفقي على الشاشة. يتم تعيين مدة الصورة المتحركة على 40 ملي ثانية والمسافة مسافة السفر 40 بكسل. كل 10 مللي ثانية، وهو معدّل تبديل اللقطات التلقائي، يتحرّك الجسم أفقيًا بمقدار 10 بكسل. في نهاية 40 ملي ثانية، تتوقف الصورة المتحركة، وينتهي موضع الكائن عند 40 أفقيًا. هذا مثال على رسم متحرك مزود باستكمال خطي، مما يعني يتحرك الكائن بسرعة ثابتة.

الشكل 1. مثال على حركة خطية

يمكنك أيضًا تحديد ملفات متحركة لتكون لها عملية تداخل غير خطية. يوضح الشكل 2 كائن افتراضي يتسارع في بداية الرسم المتحرك ويتباطأ عند نهاية الرسوم المتحركة. لا يزال الكائن يتحرك 40 بكسل خلال 40 ملي ثانية، ولكن بشكل غير خطي. في جلسة المعمل، تبدأ هذه الحركة، تتسارع هذه الحركة حتى نقطة المنتصف ثم تقل في منتصف الطريق حتى نهاية الرسوم المتحركة. وكما يوضح الشكل 2، فإن المسافة المقطوعة في بداية ونهاية الرسوم المتحركة أقل من المنتصف.

الشكل 2. مثال على الرسوم المتحركة غير الخطية

دعونا نلقي نظرة مفصلة على كيفية تضمين المكونات المهمة لنظام الرسوم المتحركة للخصائص بحساب الرسوم المتحركة مثل تلك الموضحة أعلاه. يوضّح الشكل 3 كيفية عمل الفئات الرئيسية مع بعضها.

الشكل 3: كيفية حساب الصور المتحركة

يتتبّع عنصر ValueAnimator توقيت الصورة المتحركة، مثل المدة التي تم فيها تشغيل الصورة المتحركة والقيمة الحالية للخاصية التي يتم تحريكها.

يتضمّن ValueAnimator السمة TimeInterpolator التي تحدّد استقراء الصور المتحركة، والسمة TypeEvaluator التي تحدّد كيفية حساب القيم الخاصة بالخاصية. المتحركة. على سبيل المثال، في الشكل 2، سيكون TimeInterpolator المستخدَم هو ستكون قيمة AccelerateDecelerateInterpolator وTypeEvaluator هي IntEvaluator.

لبدء حركة، أنشئ ValueAnimator وأضِف إليه قيم البدء والانتهاء للخاصية التي تريد أن تنشئ لها حركة، بالإضافة إلى مدة الحركة. عند استدعاء "start()" الصورة المتحركة تبدأ. خلال الصورة المتحركة بأكملها، يحسب ValueAnimator الجزء المنقضي بين 0 و1، استنادًا إلى مدة الصورة المتحركة والوقت المنقضي. تشير رسالة الأشكال البيانية يمثل الكسر المنقضي النسبة المئوية لوقت اكتمال الرسم المتحرك، 0 يعني 0% و1 يعني 100٪. على سبيل المثال، في الشكل 1، سيكون الجزء المنقضي عند t = 10 ملي ثانية هو 0.25 لأنّ المدة الإجمالية هي t = 40 ملي ثانية.

عند إتمام ValueAnimator لحساب الكسر المنقضي، فإنه بـ TimeInterpolator المعينة حاليًا، لحساب الكسور المستورَدة. يربط الكسر المُقتطع الكسر المنقضي بكسر جديد يراعي المدة الزمنية التي تم ضبطها. على سبيل المثال، في الشكل 2، بسبب تسارع الحركة المتحركة ببطء، يكون الجزء المُدرَج، الذي يقارب 0.15، أقل من الجزء المنقضي، 0.25، عند t = 10 مللي ثانية. في الشكل 1، يكون الجزء المُدرَج دائمًا هو نفسه الجزء المنقضي.

عند احتساب الكسر المُدرَج، يُطلِب ValueAnimator TypeEvaluator المناسب، لاحتساب قيمة السمة التي يتمّ تطبيقها عليها مؤثرًا متحركًا، استنادًا إلى الكسر المُدرَج والقيمة الافتتاحية والقيمة النهائية للمؤثر المتحرك. على سبيل المثال، في الشكل 2، كان الكسر المستورَد 0 .15 عند t = 10 ملي ثانية، وبالتالي ستكون قيمة الخاصية في ذلك الوقت 0 .15 × (40 - 0) أو 6.

الفرق بين الرسوم المتحركة للموقع والرسوم المتحركة للعرض

يوفّر نظام عرض الصور المتحركة إمكانية إضافة تأثيرات حركية إلى View فقط. لذا، إذا أردت إضافة تأثيرات حركية إلى كائنات غير View، عليك تنفيذ التعليمات البرمجية الخاصة بك للقيام بذلك. كما أن نظام عرض الرسوم المتحركة مقيد في أنه يعرض بعض جوانب كائن View لتحريكه، مثل التحجيم تدوير العرض وليس لون الخلفية مثلاً.

ومن عيوب نظام الرسوم المتحركة للعرض أيضًا أنّه لا يعدّل سوى مكان رسم العرض، وليس العرض نفسه. فعلى سبيل المثال، إذا قمت بتحريك زر لتحريك عبر الشاشة، يتم رسم الزر بشكل صحيح، ولكن يتم رسم الموقع الفعلي الذي يمكنك النقر فيه لا يتغير، لذلك عليك تنفيذ منطقك الخاص للتعامل مع هذا.

وباستخدام نظام الصور المتحركة للخصائص، تتم إزالة هذه القيود تمامًا، ويمكنك إضافة تأثيرات متحركة لأي خاصية لأي كائن (Views and non-Views) ويتم تعديل الكائن نفسه فعليًا. كما يعد نظام الرسوم المتحركة للخصائص أكثر قوة في طريقة تنفيذ الرسوم المتحركة. على مستوىٍ عالٍ، يمكنك تعيين مُشغِّلِي الرسوم المتحركة إلى السمات التي تريد أن تضيف إليها حركة، مثل اللون أو الموضع أو الحجم، ويمكنك تحديد جوانب من الحركة، مثل الاستقراء و مزامنة مشغِّلي الرسوم المتحركة المتعدّدين.

مع ذلك، يستغرق إعداد نظام عرض الصور المتحركة وقتًا أقل ويتطلب تعليمات برمجية أقل. ما إذا كانت الصورة المتحركة لعرض الصورة المتحركة توفر كل الإجراءات المطلوبة، أو إذا كانت الرموز الحالية بالطريقة التي تريدها، ليس هناك حاجة لاستخدام نظام الرسوم المتحركة للخصائص. قد يكون من المفيد أيضًا استخدام نظامَي الرسوم المتحركة في حالات مختلفة إذا ظهرت حالة الاستخدام.

نظرة عامة على واجهة برمجة التطبيقات

يمكنك العثور على معظم واجهات برمجة التطبيقات لنظام صور المواقع المتحركة في android.animation. بما أنّ نظام الرسوم المتحرّكة للعرض يحدّد العديد من الموسّعات في android.view.animation، يمكنك استخدام هذه الموسّعات في نظام الرسوم المتحرّكة للموقع أيضًا. تصف الجداول التالية المكونات الرئيسية لنظام الرسوم المتحركة في الموقع.

توفّر فئة Animator البنية الأساسية لإنشاء الصور المتحركة. أنت لا تستخدم عادةً هذه الفئة مباشرةً لأنها توفر الحد الأدنى الوظيفة التي يجب توسيعها لإتاحة القيم المتحركة بالكامل. ما يلي: تمتد الفئات الفرعية إلى Animator:

الجدول 1: أخصائيو الرسوم المتحركة

الفئة الوصف
ValueAnimator محرك التوقيت الرئيسي لحركة الخاصية الذي يحسب أيضًا قيم المطلوب تطبيق مؤثرات حركية عليها. فهو يتضمن كل الوظائف الأساسية التي تحتسب الرسوم المتحركة ويحتوي على تفاصيل التوقيت لكل رسم متحرك، ومعلومات حول ما إذا كان تكرار الرسوم المتحركة، والمستمعين الذين يتلقون أحداث تحديث، والقدرة على ضبط خيارات الأنواع لتقييمها. هناك جزآن للخصائص المتحركة: حساب الخصائص المتحركة وتعيين تلك القيم على الكائن والخاصية المتحركة. لا ينفّذ ValueAnimator القطعة الثانية، لذا عليك الاستماع إلى التعديلات على القيم التي يحتسِبها ValueAnimator و تعديل الكائنات التي تريد تحريكها باستخدام منطقك الخاص. راجِع القسم المتعلق بموضوع التأثيرات المتحركة باستخدام ValueAnimator للحصول على مزيد من المعلومات.
ObjectAnimator فئة فرعية من ValueAnimator تسمح لك بتحديد هدف خاصية الكائن والكائن لتحريكه. تعدّل هذه الفئة السمة وفقًا لذلك عند حساب قيمة جديدة للحركة. عليك استخدام ObjectAnimator في معظم الأحيان، لأنّه يسهّل عملية إضافة مؤثرات متحركة إلى القيم على العناصر المستهدَفة. ومع ذلك، قد تحتاج أحيانًا إلى استخدام ValueAnimator مباشرةً لأنّ ObjectAnimator تفرض بعض القيود الإضافية، مثل اشتراط توفُّر محدد لأساليب الوصول إلى الكائن المستهدَف.
AnimatorSet توفّر آلية لتجميع الرسومات المتحركة معًا كي يتم تشغيلها في سياق بعضها. يمكنك ضبط المؤثرات المتحركة بحيث يتم تشغيلها معًا أو بشكل تسلسلي أو بعد تأخير محدّد. راجع القسم الذي يتناول تصميم موقع إلكتروني متعدد باستخدام "مجموعات الصور المتحركة" للحصول على مزيد من المعلومات.

يحدّد المقيّمون لنظام الرسوم المتحركة للموقع كيفية احتساب القيم لسمة معيّنة. وتستخدِم هذه العناصر بيانات التوقيت التي تقدّمها فئة Animator وقيمة بداية ونهاية الصورة المتحركة، وتحسب القيم المتحركة للعنصر استنادًا إلى هذه البيانات. يوفّر نظام الصور المتحركة في الموقع التقييمات التالية:

الجدول 2: المقيّمون

الصف/الواجهة الوصف
IntEvaluator المقيِّم التلقائي الذي يحتسب القيم الخاصة بسمات int
FloatEvaluator أداة التقييم التلقائية لاحتساب قيم السمات float
ArgbEvaluator أداة التقييم التلقائية لاحتساب قيم خصائص اللون التي يتم تمثيلها كقيم سداسية عشرية
TypeEvaluator واجهة تتيح لك إنشاء تقييم خاص بك إذا كنت تضيف تأثيرًا متحركًا إلى سمة عنصر ليست int أو float أو لونًا، عليك تنفيذ واجهة TypeEvaluator لتحديد كيفية احتساب القيم المتحرّكة لسمة العنصر. يمكنك أيضًا تحديد قيمة TypeEvaluator مخصّصة لـ int وfloat واللون. إذا كنت تريد معالجة هذه الأنواع بشكل مختلف عن السلوك الافتراضي. اطّلِع على القسم حول استخدام TypeEvaluator للحصول على مزيد من المعلومات عن كيفية كتابة أداة تقييم مخصّصة.

يحدد محدِّد الوقت كيفية حساب القيم الخاصة في الرسوم المتحركة وظيفة الوقت. على سبيل المثال، يمكنك تحديد أن تحدث الصور المتحركة بشكل خطي على مستوى الحركة بأكملها، ما يعني أنّ الحركة تتحرك بالتساوي طوال الوقت، أو يمكنك تحديد أن تستخدم الصور المتحركة وقتًا غير خطي، على سبيل المثال، زيادة السرعة في البداية وتقليلها في نهاية الحركة. يصف الجدول 3 أدوات الاستيفاء المضمَّنة في android.view.animation. إذا لم يكن أيّ من الموسّعات المقدَّمة مناسبًا لاحتياجاتك، يمكنك تنفيذ واجهة TimeInterpolator وإنشاء واجهة خاصة بك. راجِع مقالة استخدام أدوات الاستيفاء لمزيد من المعلومات عن طريقة كتابة نص مخصّص. أداة التعديل.

الجدول 3. أدوات احتساب معدل التغير في الصور المتحركة

الفئة/الواجهة الوصف
AccelerateDecelerateInterpolator يشير ذلك المصطلح إلى أداة استقراء معدّل يبدأ بتغيُّره وينتهي ببطء ولكنه يتسارع بشكل أسرع. من المنتصف.
AccelerateInterpolator يشير ذلك المصطلح إلى أداة استقراء معدّل يبدأ بتغيّر مسارها ببطء ثم على الأقل. يتسارع.
AnticipateInterpolator أداة إدخال المحتوى الذي يبدأ تغييره بالوراء ثم الانتقال للأمام
AnticipateOvershootInterpolator أداة ربط يبدأ تغيُّرها للخلف ثم يندفع إلى الأمام ويتجاوز القيمة المستهدَفة، ثم يعود أخيرًا إلى القيمة النهائية.
BounceInterpolator أداة ربط ينعكس تغيُّرها في النهاية.
CycleInterpolator أداة ربط تكرّر صورتها المتحركة لعدد دورات محدّد.
DecelerateInterpolator أداة تقريب يبدأ معدّل تغيُّرها بسرعة ثم يتباطأ.
LinearInterpolator يشير ذلك المصطلح إلى أداة الاستيفاء التي يكون معدّل تغييرها ثابتًا.
OvershootInterpolator يشير هذا المصطلح إلى أداة تعديل البيانات التي يتحرك التغيير للأمام ويتجاوز القيمة الأخيرة. يعود.
TimeInterpolator واجهة تتيح لك تنفيذ مترجمك الخاص.

إضافة تأثيرات متحركة باستخدام ValueAnimator

تتيح لك فئة ValueAnimator إضافة تأثيرات متحركة إلى قيم من نوع معيّن مدّة الحركة من خلال تحديد مجموعة من قيم int أو float أو قيم الألوان التي تريد إضافة تأثيرات متحركة إليها. تحصل على ValueAnimator من خلال استدعاء أحد طرق المصنع: ofInt() أو ofFloat() أو ofObject() مثلاً:

Kotlin

ValueAnimator.ofFloat(0f, 100f).apply {
    duration = 1000
    start()
}

Java

ValueAnimator animation = ValueAnimator.ofFloat(0f, 100f);
animation.setDuration(1000);
animation.start();

في هذا الرمز البرمجي، يبدأ ValueAnimator في احتساب قيم التأثير المتحرك بين 0 و100 لمدة 1000 ملي ثانية عند تنفيذ الطريقة start().

يمكنك أيضًا تحديد نوع مخصّص لتحريكه من خلال تنفيذ ما يلي:

Kotlin

ValueAnimator.ofObject(MyTypeEvaluator(), startPropertyValue, endPropertyValue).apply {
    duration = 1000
    start()
}

Java

ValueAnimator animation = ValueAnimator.ofObject(new MyTypeEvaluator(), startPropertyValue, endPropertyValue);
animation.setDuration(1000);
animation.start();

في هذه التعليمة البرمجية، يبدأ ValueAnimator بحساب قيم المؤثر المتحرك بين startPropertyValue وendPropertyValue باستخدام منطق الذي يوفّره MyTypeEvaluator لمدة 1000 ملي ثانية، عند تنفيذ الطريقة start().

يمكنك استخدام قيم الرسوم المتحركة عن طريق إضافة AnimatorUpdateListener إلى الكائن ValueAnimator، كما هو موضح في الرمز التالي:

Kotlin

ValueAnimator.ofObject(...).apply {
    ...
    addUpdateListener { updatedAnimation ->
        // You can use the animated value in a property that uses the
        // same type as the animation. In this case, you can use the
        // float value in the translationX property.
        textView.translationX = updatedAnimation.animatedValue as Float
    }
    ...
}

Java

animation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator updatedAnimation) {
        // You can use the animated value in a property that uses the
        // same type as the animation. In this case, you can use the
        // float value in the translationX property.
        float animatedValue = (float)updatedAnimation.getAnimatedValue();
        textView.setTranslationX(animatedValue);
    }
});

في onAnimationUpdate() يمكنك من خلاله الوصول إلى قيمة الرسوم المتحركة المحدَّثة واستخدامها في خاصية إحدى طرق العرض الخاصة بك. لمزيد من المعلومات حول المستمعين، راجِع القسم حول أدوات معالجة الصور المتحركة:

إنشاء تأثيرات متحركة باستخدام ObjectAnimator

ObjectAnimator هي فئة فرعية من ValueAnimator (المُناقشة في القسم السابق)، وهي تجمع بين محرك توقيت وحساب القيمة في ValueAnimator مع إمكانية إضافة مؤثرات متحركة إلى خاصيّة مُسمّاة لعنصر مستهدف. هذا يجعل تحريك أي كائن بشكل أسهل بكثير، حيث لم تعد بحاجة إلى تنفيذ ValueAnimator.AnimatorUpdateListener، لأنه يتم تحديث الخاصية المتحركة تلقائيًا.

يتشابه إنشاء مثيل ObjectAnimator مع ValueAnimator، ولكن يمكنك أيضًا تحديد الكائن واسم خاصية ذلك الكائن (على النحو التالي: سلسلة) بالإضافة إلى القيم المطلوب تحريكها بين:

Kotlin

ObjectAnimator.ofFloat(textView, "translationX", 100f).apply {
    duration = 1000
    start()
}

Java

ObjectAnimator animation = ObjectAnimator.ofFloat(textView, "translationX", 100f);
animation.setDuration(1000);
animation.start();

لجعل ObjectAnimator تعديل المواقع بشكل صحيح، يجب عليك القيام بما يلي:

  • يجب أن يكون لخاصية الكائن الذي تقوم بتحريكه دالة setter (في حالة الجمل) على شكل set<PropertyName>() لأنّ ObjectAnimator يقوم بتحديث الخاصية تلقائيًا أثناء تشغيل الحركة، يجب أن يكون قادرًا على الوصول إليها باستخدام طريقة التعيين هذه. على سبيل المثال، إذا كان اسم السمة هو foo، يجب تنفيذ ما يلي: على طريقة setFoo(). إذا لم تكن طريقة setter هذه موجودة، يكون لديك ثلاثة الخيارات:
    • أضف طريقة setter إلى الفئة إذا كنت تملك الحق في ذلك.
    • استخدِم فئة غلاف لديك حقوق تغييرها واطلب من هذا الغلاف تلقّي قيمة باستخدام طريقة ضبط صالحة وإعادة توجيهها إلى العنصر الأصلي.
    • يمكنك استخدام ValueAnimator كبديل.
  • إذا حدّدت قيمة واحدة فقط للمَعلمة values... في إحدى طُرق المصنع ObjectAnimator، يُفترض أنّها القيمة النهائية للحركة. وبالتالي، يجب أن تحتوي خاصية الكائن التي تعمل على تحريكها على دالة getter يُستخدم للحصول على القيمة الأولية للرسوم المتحركة. يجب أن تكون دالة الحصول على البيانات على شكل get<PropertyName>(). على سبيل المثال، إذا كان اسم السمة هو foo، يجب أن تتوفّر لديك طريقة getFoo().
  • يجب أن طرق getter (إذا لزم الأمر) والتعيين للخاصية التي تقوم بتحريكها تعمل على نفس نوع قيم البداية والنهاية التي تحددها إلى ObjectAnimator. على سبيل المثال، يجب أن يكون لديك targetObject.setPropName(float) وtargetObject.getPropName() في حال إنشاء ObjectAnimator التالي:
    ObjectAnimator.ofFloat(targetObject, "propName", 1f)
  • وبناءً على الخاصية أو الكائن الذي تقوم بتحريكه، قد تحتاج إلى استدعاء طريقة invalidate() في طريقة العرض لإجبار الشاشة على إعادة رسمها باستخدام القيم المتحركة المحدثة. يمكنك إجراء ذلك في onAnimationUpdate() معاودة الاتصال. على سبيل المثال، لا يؤدي إضافة تأثيرات متحركة إلى سمة اللون في عنصر Drawable إلا إلى تعديلات على الشاشة عندما يعيد هذا العنصر رسم نفسه. كل أماكن تحديد المواقع على "العرض"، مثل setAlpha() وsetTranslationX() إلغاء صلاحية العرض على نحو سليم، فلا يلزم إلغاء صلاحية العرض عند استدعاء هذه باستخدام قيم جديدة. لمزيد من المعلومات عن أدوات الاستماع، اطّلِع على القسم المعنيّ أدوات الاستماع إلى الرسوم المتحركة.

تصميم رقصات متعدّدة للصور المتحركة باستخدام AnimatorSet

في كثير من الحالات، تريد تشغيل رسم متحرك يعتمد على وقت بدء أو ينتهي. يتيح نظام Android تجميع الصور المتحركة معًا في AnimatorSet، وذلك لتتمكّن من تحديد ما إذا كان يجب بدء الصور المتحركة أم لا في الوقت نفسه أو بشكل تسلسلي أو بعد مهلة محددة. يمكنك أيضًا تداخل عناصر AnimatorSet مع بعضها.

يُشغِّل مقتطف الرمز التالي ملف Animator التالي. بالشكل التالي:

  1. يشغّل bounceAnim.
  2. يتم تشغيل squashAnim1 وsquashAnim2 وstretchAnim1 و stretchAnim2 في نفس الوقت.
  3. يتم تشغيل bounceBackAnim.
  4. يشغّل fadeAnim.

Kotlin

val bouncer = AnimatorSet().apply {
    play(bounceAnim).before(squashAnim1)
    play(squashAnim1).with(squashAnim2)
    play(squashAnim1).with(stretchAnim1)
    play(squashAnim1).with(stretchAnim2)
    play(bounceBackAnim).after(stretchAnim2)
}
val fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f).apply {
    duration = 250
}
AnimatorSet().apply {
    play(bouncer).before(fadeAnim)
    start()
}

Java

AnimatorSet bouncer = new AnimatorSet();
bouncer.play(bounceAnim).before(squashAnim1);
bouncer.play(squashAnim1).with(squashAnim2);
bouncer.play(squashAnim1).with(stretchAnim1);
bouncer.play(squashAnim1).with(stretchAnim2);
bouncer.play(bounceBackAnim).after(stretchAnim2);
ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
fadeAnim.setDuration(250);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(bouncer).before(fadeAnim);
animatorSet.start();

أدوات معالجة الصور المتحركة

يمكنك الاستماع إلى الأحداث المهمة أثناء مدة عرض الصورة المتحركة باستخدام مستمعي الأحداث الموضّحين أدناه.

  • Animator.AnimatorListener
    • onAnimationStart() - يتمّ استدعاؤه عند بدء الصورة المتحركة.
    • onAnimationEnd() - يتمّ استدعاؤه عند انتهاء الصورة المتحركة.
    • onAnimationRepeat(): يتم استدعاؤه عندما يتم تكرار الصورة المتحركة من تلقاء نفسها.
    • onAnimationCancel(): يتمّ استدعاؤها عند إلغاء الصورة المتحركة. تؤدي الرسوم المتحركة المُلغاة أيضًا إلى استدعاء onAnimationEnd()، بغض النظر عن كيفية إنهائها.
  • ValueAnimator.AnimatorUpdateListener
    • onAnimationUpdate() - يتم استدعاؤه في كل إطار في الصورة المتحركة. يمكنك الاستماع إلى هذا الحدث ل استخدام القيم المحسوبة التي أنشأها ValueAnimator أثناء عرض متحرك. لاستخدام القيمة، أدخِل طلب بحث عن الكائن ValueAnimator. يتم تمريره إلى الحدث للحصول على القيمة المتحركة الحالية باستخدام الطريقة getAnimatedValue(). إن تنفيذ هذه يجب توفير أداة معالجة الأحداث في حال استخدام ValueAnimator.

      اعتمادًا على الخاصية أو الكائن الذي تقوم بتحريكه، قد تحتاج إلى استدعاء invalidate() في طبقة عرض لفرض هذه المنطقة من لإعادة رسم نفسها باستخدام القيم المتحركة الجديدة. على سبيل المثال، يؤدي تحريك لا تتسبب خاصية اللون لكائن قابل للرسم في إجراء تحديثات على الشاشة إلا عندما يكون هذا الكائن يعيد رسم نفسه. تُبطل جميع أدوات ضبط السمات في View صلاحية View بشكل صحيح، مثل setAlpha() و setTranslationX()، لذا لا تحتاج إلى إلغاء صلاحية View عند استدعاء هذه الطرق بقيم جديدة.

يمكنك تمديد الصف AnimatorListenerAdapter بدلاً من إذا كنت لا تستخدم واجهة Animator.AnimatorListener تريد تطبيق جميع طرق Animator.AnimatorListener من واجهة pyplot. يوفّر الصف AnimatorListenerAdapter قيمة فارغة. وعمليات التنفيذ للطرق التي يمكنك اختيار تجاوزها.

على سبيل المثال، ينشئ المقتطف التالي من التعليمات البرمجية AnimatorListenerAdapter لطلب onAnimationEnd() فقط:

Kotlin

ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f).apply {
    duration = 250
    addListener(object : AnimatorListenerAdapter() {
        override fun onAnimationEnd(animation: Animator) {
            balls.remove((animation as ObjectAnimator).target)
        }
    })
}

Java

ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
fadeAnim.setDuration(250);
fadeAnim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator animation) {
    balls.remove(((ObjectAnimator)animation).getTarget());
}

تحريك تغييرات التنسيق لكائنات ViewGroup

يوفّر نظام الصور المتحركة للخصائص إمكانية تحريك التغييرات على كائنات ViewGroup. فضلاً عن توفير طريقة سهلة لتحريك عناصر العرض نفسها.

يمكنك تحريك تغييرات التنسيق داخل ViewGroup باستخدام صف واحد (LayoutTransition). يمكن لطرق العرض داخل ViewGroup حركة تظهر وتختفي عند إضافتها إلى أو إزالتها من ViewGroup أو عند استدعاء عنصر طريقة واحدة (setVisibility()) مع VISIBLE أو INVISIBLE أو GONE يمكن أيضًا أن تتضمن طرق العرض المتبقية تتحرك في مواضعها الجديدة عند إضافة طرق عرض أو إزالتها. يمكنك تحديد الحركات التالية في عنصر LayoutTransition من خلال استدعاء setAnimator() وإدخال عنصر Animator مع أحد ثوابت LayoutTransition التالية:

  • APPEARING: علامة تشير إلى الصورة المتحركة التي يتم تشغيلها على العناصر التي تظهر في الحاوية
  • CHANGE_APPEARING: علامة تشير إلى الصورة المتحركة التي يتم عرضها على العناصر التي تتغيّر بسبب ظهور عنصر جديد في الحاوية.
  • DISAPPEARING - علامة تشير إلى الصورة المتحركة التي يتم عرضها على العناصر التي تختفي من الحاوية
  • CHANGE_DISAPPEARING - علامة تشير إلى الصورة المتحركة التي تعمل على العناصر تتغير بسبب اختفاء عنصر من الحاوية.

يمكنك تحديد الصور المتحركة المخصصة لهذه الأنواع الأربعة من الأحداث لتخصيص مظهر انتقالات التخطيط أو الاكتفاء بإخبار نظام الرسوم المتحركة باستخدام الرسوم المتحركة الافتراضية.

لضبط السمة android:animateLayoutchanges على true لعنصر ViewGroup، اتّبِع الخطوات التالية:

<LinearLayout
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:id="@+id/verticalContainer"
    android:animateLayoutChanges="true" />

يؤدي ضبط هذه السمة على true إلى إضافة صور متحركة تلقائيًا إلى "عناصر العرض" التي تتم إضافتها أو إزالتها من مجموعة ViewGroup، بالإضافة إلى "عناصر العرض" المتبقية في مجموعة ViewGroup.

تحريك تغييرات حالة العرض باستخدام StateListAnimator

تتيح لك الفئة StateListAnimator تحديد الرسوم المتحركة التي تعمل عندما تتغير حالة العرض. يتصرّف هذا العنصر كعنصر ملفّف لعنصر Animator، ويُطلِق هذه الصورة المتحركة عند تغيُّر حالة عرض محدّدة (مثل "مضغوط" أو "مركّز عليه").

يمكن تحديد StateListAnimator في مورد XML باستخدام جذر. عنصر <selector> وعناصر <item> الثانوية التي يحدد كل منها حالة عرض مختلفة تحدّدها الفئة StateListAnimator. يحتوي كل <item> على تعريف لمجموعة رسوم متحركة للموقع.

على سبيل المثال، ينشئ الملف التالي مُشغِّلًا للصور المتحركة في قائمة الحالات يغيّر مقياس x وy للعرض عند الضغط عليه:

res/xml/animate_scale.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- the pressed state; increase x and y size to 150% -->
    <item android:state_pressed="true">
        <set>
            <objectAnimator android:propertyName="scaleX"
                android:duration="@android:integer/config_shortAnimTime"
                android:valueTo="1.5"
                android:valueType="floatType"/>
            <objectAnimator android:propertyName="scaleY"
                android:duration="@android:integer/config_shortAnimTime"
                android:valueTo="1.5"
                android:valueType="floatType"/>
        </set>
    </item>
    <!-- the default, non-pressed state; set x and y size to 100% -->
    <item android:state_pressed="false">
        <set>
            <objectAnimator android:propertyName="scaleX"
                android:duration="@android:integer/config_shortAnimTime"
                android:valueTo="1"
                android:valueType="floatType"/>
            <objectAnimator android:propertyName="scaleY"
                android:duration="@android:integer/config_shortAnimTime"
                android:valueTo="1"
                android:valueType="floatType"/>
        </set>
    </item>
</selector>

لإرفاق الصورة المتحركة لقائمة الحالات بأحد طرق العرض، أضف android:stateListAnimator على النحو التالي:

<Button android:stateListAnimator="@xml/animate_scale"
        ... />

يتم الآن استخدام الرسوم المتحرّكة المحدّدة في animate_scale.xml عند تغيُّر حالة هذا الزر.

أو بدلاً من ذلك، يمكنك تعيين مُشغِّل قائمة حالات إلى عرض في الرمز البرمجي باستخدام الأسلوب AnimatorInflater.loadStateListAnimator()، وتعيين المشغِّل إلى العرض باستخدام الأسلوب View.setStateListAnimator().

أو بدلاً من تحريك خصائص طريقة العرض، يمكنك تشغيل صورة متحركة قابلة للرسم بين تغير الحالة، باستخدام AnimatedStateListDrawable. يمكن لبعض أدوات النظام في ويستخدم Android 5.0 هذه الصور المتحركة تلقائيًا. يوضّح المثال التالي كيفية تحديد AnimatedStateListDrawable كمرجع XML:

<!-- res/drawable/myanimstatedrawable.xml -->
<animated-selector
    xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- provide a different drawable for each state-->
    <item android:id="@+id/pressed" android:drawable="@drawable/drawableP"
        android:state_pressed="true"/>
    <item android:id="@+id/focused" android:drawable="@drawable/drawableF"
        android:state_focused="true"/>
    <item android:id="@id/default"
        android:drawable="@drawable/drawableD"/>

    <!-- specify a transition -->
    <transition android:fromId="@+id/default" android:toId="@+id/pressed">
        <animation-list>
            <item android:duration="15" android:drawable="@drawable/dt1"/>
            <item android:duration="15" android:drawable="@drawable/dt2"/>
            ...
        </animation-list>
    </transition>
    ...
</animated-selector>

استخدام TypeEvaluator

إذا كنت تريد إضافة تأثير متحرك إلى نوع غير معروف لنظام Android، يمكنك إنشاء نوعك الخاص والمقيِّم من خلال تنفيذ واجهة TypeEvaluator. إن الأنواع التي التي يعرفها نظام Android هي int، أو float، أو أحد الألوان، وهي متوافق مع الأنواع IntEvaluator وFloatEvaluator وArgbEvaluator المقيّمين.

هناك طريقة واحدة فقط لتنفيذها في واجهة TypeEvaluator وهي طريقة evaluate(). يتيح ذلك لبرنامج التحريك الذي تستخدمه عرض قيمة مناسبة للعنصر المتحرّك في النقطة الحالية للحركة. توضِّح فئة FloatEvaluator كيفية إجراء ذلك:

Kotlin

private class FloatEvaluator : TypeEvaluator<Any> {

    override fun evaluate(fraction: Float, startValue: Any, endValue: Any): Any {
        return (startValue as Number).toFloat().let { startFloat ->
            startFloat + fraction * ((endValue as Number).toFloat() - startFloat)
        }
    }

}

Java

public class FloatEvaluator implements TypeEvaluator {

    public Object evaluate(float fraction, Object startValue, Object endValue) {
        float startFloat = ((Number) startValue).floatValue();
        return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);
    }
}

ملاحظة: عند تشغيل ValueAnimator (أو ObjectAnimator)، يتم احتساب الكسر الحالي المنقضي من المتحرك (قيمة تتراوح بين 0 و1)، ثم احتساب نسخة متداخلة من ذلك استنادًا إلى أداة الاستقراء التي تستخدمها. الكسر المستورَد هو ما تتلقّاه TypeEvaluator من خلال المعلمة fraction، لذا يمكنك لا يجب أن تأخذ في الاعتبار أداة الاستيفاء عند احتساب القيم المتحركة.

استخدام أدوات احتساب معدل التغير في الصور المتحركة

يحدِّد الموسّع كيفية احتساب قيم معيّنة في الصورة المتحركة كدالّة على الوقت. على سبيل المثال، يمكنك تحديد الرسوم المتحركة التي تحدث خطيًا عبر الرسوم المتحركة بأكملها، مما يعني أن الرسوم المتحركة تتحرك بالتساوي طوال الوقت، أو يمكنك تحديد الرسوم المتحركة لاستخدامها أي نظام غير خطي، مثل استخدام التسارع أو التباطؤ في بداية أو نهاية الرسوم المتحركة.

تتلقّى أدوات الاستبدال في نظام الصور المتحركة جزءًا من أدوات الرسوم المتحركة يمثّل الوقت المنقضي للصورة المتحركة. تعدّل أدوات الاستبدال هذا الجزء لتتطابق مع نوع الحركة التي تهدف إلى تقديمها. يوفّر نظام Android مجموعة من الموسّعات الشائعة في android.view.animation package. إذا لم يناسب أيّ منها احتياجاتك، يمكنك تنفيذ واجهة TimeInterpolator وإنشاء واجهتك الخاصة.

على سبيل المثال، في ما يلي مقارنة بين كيفية احتساب المقسّمات المتداخلة من خلال أداة الاستبدال التلقائية AccelerateDecelerateInterpolator وLinearInterpolator. ولا تؤثر القيمة LinearInterpolator في الكسر المنقضي. يتسارع AccelerateDecelerateInterpolator إلى الصورة المتحركة يتراجع منها. تحدد الطرق التالية منطق أدوات الاستيفاء هذه:

AccelerateDecelerateInterpolator

Kotlin

override fun getInterpolation(input: Float): Float =
        (Math.cos((input + 1) * Math.PI) / 2.0f).toFloat() + 0.5f

Java

@Override
public float getInterpolation(float input) {
    return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
}

LinearInterpolator

Kotlin

override fun getInterpolation(input: Float): Float = input

Java

@Override
public float getInterpolation(float input) {
    return input;
}

يمثّل الجدول التالي القيم التقريبية التي يتم احتسابها من خلال interpolator هذا لحركة متحرّكة تستمر لمدة 1000 ملي ثانية:

الوقت المنقضي بالمللي ثانية الكسر المنقضي/الكسر المستيفَى (خطي) جزء مُدرَج (تسريع/تباطؤ)
0 0 0
200 .2 .1
400 .4 ‎.345
600 6. ‎.654
800 8. 9.
1000 1 1

كما يبيّن الجدول، تغيّر LinearInterpolator القيم. بنفس السرعة، 2. لكل 200 ملّي ثانية تمر. يغيّر AccelerateDecelerateInterpolator القيم بشكل أسرع من LinearInterpolator بين 200 و600 ملي ثانية، وبشكل أبطأ بين 600 و 1000 ملي ثانية.

تحديد الإطارات الرئيسية

يتألّف عنصر Keyframe من زوج وقت/قيمة يتيح لك تحديد حالة معيّنة في وقت معيّن من الحركة. يمكن أن يكون لكل إطار رئيسي أيضًا محوره أداة الاستيفاء للتحكّم في سلوك الحركة في الفاصل الزمني بين وقت الإطار الرئيسي ووقت هذا الإطار الرئيسي.

لإنشاء مثيل كائن Keyframe، يجب استخدام أحد الشركات المصنِّعة. أو ofInt() أو ofFloat() أو ofObject() للحصول على النوع المناسب من Keyframe. ثم تتصل طريقة المصنع ofKeyframe() الحصول على كائن PropertyValuesHolder. بعد الحصول على العنصر، يمكنك الحصول على أداة تحريك من خلال تمرير عنصر PropertyValuesHolder والعنصر المطلوب تحريكه. يوضح مقتطف الرمز التالي كيفية إجراء ذلك:

Kotlin

val kf0 = Keyframe.ofFloat(0f, 0f)
val kf1 = Keyframe.ofFloat(.5f, 360f)
val kf2 = Keyframe.ofFloat(1f, 0f)
val pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2)
ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation).apply {
    duration = 5000
}

Java

Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
Keyframe kf1 = Keyframe.ofFloat(.5f, 360f);
Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);
ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation);
rotationAnim.setDuration(5000);

عدد مرات المشاهدة

يتيح نظام الصور المتحركة للموقع الإلكتروني عرض صور متحركة سلسة لكائنات العرض، ويقدّم بعض المزايا مقارنةً بنظام الصور المتحركة للعرض. العرض حول تغيير نظام الرسوم المتحركة كائنات العرض بتغيير طريقة رسمها. تم التعامل مع ذلك في حاوية كل عرض، لأنّ العرض نفسه لم يكن يتضمّن أيّ سمات يمكن التلاعب بها. وقد أدّى ذلك إلى إضافة تأثير متحرك إلى العرض، ولكنّه لم يسبّب أي تغيير في عنصر العرض نفسه. هذا النمط إلى سلوك معين، مثل بقاء كائن ما في مكانه الأصلي، على الرغم من مرسومة على موقع مختلف على الشاشة. في Android 3.0، تمت إضافة سمات جديدة وطريقتَي الإعداد والحصول المعنيتَين للقضاء على هذا العيب.

نظام الرسوم المتحركة للممتلكات يمكنها تحريك طرق العرض على الشاشة من خلال تغيير الخصائص الفعلية في كائنات "العرض". ضِمن بالإضافة إلى ذلك، يطلق على المشاهدات أيضًا تلقائيًا اسم invalidate() لتحديث الشاشة كلما تم تغيير خصائصها. في ما يلي السمات الجديدة في الفئة View التي تسهّل الصور المتحركة للسمات:

  • translationX وtranslationY: تتحكم هذه الخصائص في مكان يقع العرض على شكل دلتا من إحداثياته اليسرى والعلوية التي يتم تعيينها حسب تخطيطه .
  • rotation وrotationX وrotationY: تتحكّم هذه الخصائص في عملية الدوران في ثنائي الأبعاد (خاصية rotation) وثلاثي الأبعاد حول نقطة المحور.
  • scaleX وscaleY: تتحكّم هذه السمات في التكبير/التصغير ثنائي الأبعاد لملف عرض حول نقطة محوره.
  • pivotX وpivotY: تتحكم هذه الخصائص في موقع النقطة المحورية، التي يحدث حولها تحويلات الدوران والتحجيم. تكون نقطة محور الدوران في منتصف الجسم تلقائيًا.
  • x وy: هذه هي خصائص منفعة بسيطة لوصف الموقع النهائي للعرض في حاويته، كمجموع للقيم المتبقية والعلوية قيم TranslateX وTranslationY.
  • alpha: يمثل شفافية ألفا في العرض. تكون هذه القيمة 1 (غير شفافة) تلقائيًا، وتكون القيمة 0 تمثّل الشفافية الكاملة (غير مرئية).

لتحريك خاصية لكائن عرض، مثل لونه أو قيمة تدويره، ما عليك سوى فعله هو إنشاء أداة حركة الخصائص وتحديد خاصية العرض التي تريد صورة متحركة. مثلاً:

Kotlin

ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f)

Java

ObjectAnimator.ofFloat(myView, "rotation", 0f, 360f);

لمزيد من المعلومات عن إنشاء مُشغِّلات الرسوم المتحرّكة، اطّلِع على الأقسام المتعلّقة بإنشاء الرسوم المتحرّكة باستخدامValueAnimator وObjectAnimator.

إنشاء تأثيرات متحركة باستخدام ViewPropertyAnimator

يوفّر ViewPropertyAnimator طريقة بسيطة لإضافة تأثيرات متحركة متعددة خصائص View بشكل متوازٍ، باستخدام قيمة Animator أساسية واحدة الخاص بك. ويعمل بشكل كبير مثل ObjectAnimator، لأنه يغيّر القيم الفعلية لخصائص الملف الشخصي، ولكنها أكثر كفاءة عند تحريك العديد من الخصائص في مرة واحدة. بالإضافة إلى ذلك، فإنّ رمز استخدام ViewPropertyAnimator هو أكثر إيجازًا وسهولة في القراءة. توضح مقتطفات الرمز التالية الاختلافات في استخدام رموز ObjectAnimator عنصرًا، عنصر واحد وObjectAnimator، وViewPropertyAnimator عند تحريك السمتَين x وy من ملف شخصي في آنٍ واحد.

كائنات عناصر متحركة متعددة

Kotlin

val animX = ObjectAnimator.ofFloat(myView, "x", 50f)
val animY = ObjectAnimator.ofFloat(myView, "y", 100f)
AnimatorSet().apply {
    playTogether(animX, animY)
    start()
}

Java

ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f);
ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f);
AnimatorSet animSetXY = new AnimatorSet();
animSetXY.playTogether(animX, animY);
animSetXY.start();

ObjectAnimator واحد

Kotlin

val pvhX = PropertyValuesHolder.ofFloat("x", 50f)
val pvhY = PropertyValuesHolder.ofFloat("y", 100f)
ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvhY).start()

Java

PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f);
ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvhY).start();

ViewPropertyAnimator

Kotlin

myView.animate().x(50f).y(100f)

Java

myView.animate().x(50f).y(100f);

للحصول على معلومات أكثر تفصيلاً حول ViewPropertyAnimator، يمكنك الاطّلاع على مطوّري تطبيقات Android المعنيّين. مدونة مشاركة.

تحديد الصور المتحركة في ملف XML

يتيح لك نظام الرسوم المتحركة للخصائص الإعلان عن الرسوم المتحركة للخصائص باستخدام XML بدلاً من برمجيًا. من خلال تحديد الصور المتحركة بتنسيق XML، يمكنك إعادة استخدام الصور المتحركة بسهولة. في أنشطة متعددة وتعديل تسلسل الرسوم المتحركة بسهولة أكبر.

لتمييز ملفات الصور المتحركة التي تستخدم واجهات برمجة التطبيقات الجديدة للصور المتحركة للخصائص عن الملفات التي تستخدم إطار عمل العرض المتحركة القديم بدءًا من الإصدار 3.1 من نظام التشغيل Android، يجب حفظ ملفات XML الخاصة برسوم متحركة للخصائص في دليل res/animator/.

تشمل فئات الرسوم المتحركة للخصائص التالية توافق إعلان XML مع علامات XML التالية:

للعثور على السمات التي يمكنك استخدامها في تعريف XML، اطّلِع على مواد مرجعية للرسوم المتحركة. يشغّل المثال التالي مجموعتي صور متحركة للكائن بالتسلسل، مع أول مجموعة متداخلة تقوم بتشغيل صور متحركة لكائن معًا:

<set android:ordering="sequentially">
    <set>
        <objectAnimator
            android:propertyName="x"
            android:duration="500"
            android:valueTo="400"
            android:valueType="intType"/>
        <objectAnimator
            android:propertyName="y"
            android:duration="500"
            android:valueTo="300"
            android:valueType="intType"/>
    </set>
    <objectAnimator
        android:propertyName="alpha"
        android:duration="500"
        android:valueTo="1f"/>
</set>

لتشغيل هذه الحركة، يجب تضخيم موارد XML في الرمز البرمجي إلى عنصر AnimatorSet، ثم ضبط العناصر المستهدفة لجميع المؤثرات الحركية. قبل بدء تشغيل الرسوم المتحركة. يؤدي استدعاء setTarget() إلى ضبط عنصر مستهدَف واحد لجميع العناصر الثانوية في AnimatorSet لتسهيل الأمر. يوضح الرمز التالي كيفية إجراء هذا:

Kotlin

(AnimatorInflater.loadAnimator(myContext, R.animator.property_animator) as AnimatorSet).apply {
    setTarget(myObject)
    start()
}

Java

AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext,
    R.animator.property_animator);
set.setTarget(myObject);
set.start();

يمكنك أيضًا الإعلان عن ValueAnimator في XML كـ كما هو موضح في المثال التالي:

<animator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:valueType="floatType"
    android:valueFrom="0f"
    android:valueTo="-100f" />

لاستخدام ValueAnimator السابق في الرمز، عليك يجب تضخيم الكائن، وإضافة AnimatorUpdateListener, والحصول على قيمة الرسوم المتحركة المحدّثة، واستخدامها في خاصية من طرق العرض، كما هو موضح في التعليمة البرمجية التالية:

Kotlin

(AnimatorInflater.loadAnimator(this, R.animator.animator) as ValueAnimator).apply {
    addUpdateListener { updatedAnimation ->
        textView.translationX = updatedAnimation.animatedValue as Float
    }

    start()
}

Java

ValueAnimator xmlAnimator = (ValueAnimator) AnimatorInflater.loadAnimator(this,
        R.animator.animator);
xmlAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator updatedAnimation) {
        float animatedValue = (float)updatedAnimation.getAnimatedValue();
        textView.setTranslationX(animatedValue);
    }
});

xmlAnimator.start();

للحصول على معلومات عن بنية XML لتحديد الصور المتحركة للخصائص، يمكنك الاطّلاع على الصورة المتحركة الموارد .

الآثار المحتملة على أداء واجهة المستخدم

إنّ الرسوم المتحرّكة التي تعدّل واجهة المستخدم تؤدي إلى زيادة في عمليات التقديم لكل إطار يتم تشغيل الرسوم المتحركة فيه. لهذا السبب، يمكن أن يؤثر استخدام الرسوم المتحرّكة المستهلكة للطاقة سلبًا في أداء تطبيقك.

تتم إضافة العمل المطلوب لتحريك واجهة المستخدم إلى مرحلة الصورة المتحركة مسار العرض. يمكنك معرفة ما إذا كانت الرسومات المتحركة تؤثر في أداء تطبيقك من خلال تفعيل ميزة رسم مخطط لعرض وحدة معالجة الرسومات ومتابعة مرحلة الرسوم المتحركة. لمزيد من المعلومات، يُرجى الاطّلاع على عرض الملف الشخصي لوحدة معالجة الرسومات. جولة تفصيلية.