يُعد نظام الصور المتحركة للخصائص إطارًا قويًا يتيح لك تحريك أي شيء تقريبًا. يمكنك تحديد حركة لتغيير أي خاصية من عناصر الكائن بمرور الوقت، بغض النظر عما إذا كانت ستظهر على الشاشة أم لا. تؤدي الحركة للخاصية إلى تغيير قيمة السمة (حقل في عنصر) خلال مدة زمنية محدّدة. لإضافة تأثيرات حركية إلى عنصر، عليك تحديد سمة الكائن التي تريد تحريكها، مثل موضع العنصر على الشاشة والمدة التي تريد إنشاء الرسم فيها والقيم التي تريد إضافة تأثيرات حركية إليها.
يتيح لك نظام الصور المتحركة للسمات تحديد الخصائص التالية للصورة المتحركة:
- المدة: يمكنك تحديد مدة الرسم المتحرك. المدة التلقائية هي 300 ملي ثانية.
- استيفاء الوقت: يمكنك تحديد طريقة احتساب قيم السمة كدالة للوقت المنقضي الحالي للصورة المتحركة.
- عدد التكرارات والسلوك: يمكنك تحديد ما إذا كنت تريد أن يتم تكرار الحركة عند وصولها إلى نهاية المدة وعدد مرات تكرار الصورة المتحركة. ويمكنك أيضًا تحديد ما إذا كنت تريد إعادة تشغيل الصورة المتحركة بالعكس. وعند ضبطها على الوضع العكسي، يتم تشغيل الصورة المتحركة للأمام ثم للخلف بشكل متكرّر إلى أن يتم الوصول إلى عدد التكرارات.
- مجموعات أدوات الصور المتحركة: يمكنك تجميع الصور المتحركة في مجموعات منطقية يتم تشغيلها معًا أو بشكل تسلسلي أو بعد تأخيرات محدّدة.
- مهلة تحديث الإطار: يمكنك تحديد عدد مرات تحديث الإطارات في الصورة المتحركة. ويتم ضبط الإعداد التلقائي على إعادة التحميل كل 10 ملي ثانية، ولكن السرعة التي يمكن لتطبيقك بها إعادة تحميل اللقطات تعتمد بشكل أساسي على مدى ازدحام النظام بشكل عام وسرعة النظام في تشغيل الموقّت الأساسي.
للاطّلاع على مثال كامل للسمات المتحركة، يمكنك الاطّلاع على الفئة ChangeColor
في النموذج Customtransition على GitHub.
آلية عمل الرسوم المتحركة في الموقع
أولاً، لنستعرض كيفية عمل الرسوم المتحركة بمثال بسيط. يوضِّح الشكل 1
جسمًا افتراضيًا متحركًا باستخدام السمة x
التي تمثِّل
موقعه الأفقي على الشاشة. يتم ضبط مدة الصورة المتحركة على 40 ملي ثانية، بينما تبلغ المسافة
التي يتم قطعها 40 بكسل. كل 10 ملي ثانية، وهو معدّل إعادة تحميل اللقطات التلقائي، يتحرك العنصر
أفقيًا بمقدار 10 بكسل. في نهاية 40 ملي ثانية، تتوقف الصورة المتحركة وينتهي العنصر في
الموضع الأفقي 40. هذا مثال على صورة متحرّكة تتضمّن استيفاءً خطيًا، ما يعني أنّ
الجسم يتحرك بسرعة ثابتة.
ويمكنك أيضًا تحديد الرسوم المتحركة للحصول على استقراء غير خطي. يوضح الشكل 2 عنصرًا افتراضيًا يتسارع في بداية الصورة المتحركة، ويسرع في نهايته. لا يزال الكائن يتحرك 40 بكسل خلال 40 ملي ثانية، ولكن بشكل غير خطي. في البداية، يتم تسريع هذه الحركة حتى تصل إلى نقطة المنتصف، ثم تنخفض سرعتها من نقطة المنتصف حتى نهايتها. كما يبيّن الشكل 2، إنّ المسافة التي تم قطعها في بداية ونهاية الصورة المتحركة أقل من المسافة التي تم قطعها في المنتصف.
لنلقِ نظرة تفصيلية على طريقة احتساب المكوّنات المهمة لنظام الصور المتحركة مثل تلك الموضّحة أعلاه. يوضّح الشكل 3 طريقة عمل الصفوف الرئيسية مع بعضها البعض.
يتتبّع الكائن ValueAnimator
توقيت الصورة المتحركة،
مثل مدة تشغيل الصورة المتحركة والقيمة الحالية للسمة
التي يحرّكها الصورة.
تحتوي السمة ValueAnimator
على TimeInterpolator
التي تحدّد استقراء الحركة، وقيمة TypeEvaluator
التي تحدّد كيفية حساب قيم السمة التي يتم تحريكها. على سبيل المثال، في الشكل 2، ستكون قيمة TimeInterpolator
المستخدَمة على شكل
AccelerateDecelerateInterpolator
وقيمة TypeEvaluator
على IntEvaluator
.
لبدء استخدام صورة متحركة، أنشِئ ValueAnimator
وأضِف قيم البداية والنهاية للسمة التي تريد تحريكها، بالإضافة إلى مدة الحركة. عند استدعاء start()
، تبدأ
الرسوم المتحركة. أثناء تحريك الصورة المتحركة بالكامل، تحتسب ValueAnimator
الكسر المنقضي بين 0 و1، وذلك استنادًا إلى مدة الصورة المتحركة والمدة المنقضية. ويمثّل
الكسر المنقضي النسبة المئوية للوقت الذي اكتملت فيه الصورة المتحركة، حيث تشير القيمة 0 إلى %0
والرقم 1 إلى %100. على سبيل المثال، في الشكل 1، سيكون الكسر المنقضي عند t = 10 ملي ثانية يساوي .25
لأنّ المدة الإجمالية هي t = 40 ملي ثانية.
عند الانتهاء من احتساب ValueAnimator
من الكسر المنقضي، يستدعي السمة TimeInterpolator
المضبوطة حاليًا لاحتساب الكسر المُدخل. يربط الكسر المضاف على سبيل المثال، في الشكل 2، وبما أنّ الحركة المتحركة تتسارع ببطء، فإنّ الكسر المضاف، وهو حوالي 15.، أقل من الكسر المنقضي، 0.25، عند t = 10 ملي ثانية. وفي الشكل 1، يكون الكسر المضاف دائمًا هو نفسه الكسر المنقضي دائمًا.
عند حساب الكسر المُدخل، يستدعي ValueAnimator
قيمة TypeEvaluator
المناسبة لحساب قيمة
الخاصية التي تحرّكها، استنادًا إلى الكسر المُدخل، وقيمة البداية،
والقيمة النهائية للحركة. على سبيل المثال، في الشكل 2، كان الكسر المدمَج 0 .15 عند t =
10 ملي ثانية، وبالتالي تكون قيمة الموقع في ذلك الوقت .15 × (40 - 0) أو 6.
أوجه الاختلاف بين الرسوم المتحركة للمكان وبين الرسوم المتحركة للعرض
يتيح نظام عرض الصور المتحركة فقط تحريك كائنات View
، لذا إذا أردت تحريك كائنات ليست View
، عليك تنفيذ رمزك الخاص لإجراء ذلك. كما أنّ نظام العرض المتحركة يوفّر إمكانية تحريك بعض العناصر من الكائن View
فقط، مثل تغيير حجم العرض
وتدويره وليس لون الخلفية، على سبيل المثال.
ومن العيوب الأخرى لنظام العرض المتحرك أنّه تم تعديل موضع رسم العرض فقط وليس العرض الفعلي بحد ذاته. على سبيل المثال، إذا أضفت تأثيرات حركية إلى زر لنقله على الشاشة، سيتم رسم الزر بشكل صحيح، إلا أنّ الموقع الفعلي الذي يمكنك النقر فيه على الزر لن يتغيّر، لذا يجب أن تطبّق منطقك الخاص للتعامل مع هذا الأمر.
عند استخدام نظام الصور المتحركة للخصائص، تتم إزالة هذه القيود بالكامل، ويمكنك إضافة تأثير متحرك إلى أي خاصية من أي كائن (Views and non-Views) وتعديل العنصر نفسه. كما يعد نظام الرسوم المتحركة للخصائص أكثر قوة في طريقة تنفيذه للصور المتحركة. يمكنك تعيين أدوات متحركة للسمات التي تريد إضافتها، مثل اللون أو الموضع أو الحجم، كما يمكنك تحديد جوانب الحركة، مثل إضافة البيانات المتحركة ومزامنة أدوات الصور المتحركة المتعددة.
ومع ذلك، يستغرق نظام الرسوم المتحركة للعرض وقتًا أقل لإعداده ويتطلب رمزًا أقل للكتابة. إذا كانت الصورة المتحركة للعرض تنجز كل ما تحتاج إلى تنفيذه أو إذا كانت الرموز البرمجية الحالية تعمل بالطريقة التي تريدها، لن يكون عليك استخدام نظام الصور المتحركة للسمات. وقد يكون من المنطقي استخدام كلا نظامَي الصور المتحركة في مواقف مختلفة إذا نشأت حالة استخدام.
نظرة عامة على واجهة برمجة التطبيقات
يمكنك العثور على معظم واجهات برمجة التطبيقات لنظام الصور المتحركة في android.animation
. بما أنّ نظام عرض الصور المتحركة
يحدّد حاليًا العديد من أدوات الاستيفاء في android.view.animation
، يمكنك
استخدام هذه الأدوات في نظام الصور المتحركة للسمات أيضًا. توضّح الجداول التالية المكوّنات الرئيسية لنظام الصور المتحركة.
توفّر الفئة Animator
البنية الأساسية لإنشاء
الصور المتحركة. أنت لا تستخدم هذه الفئة في العادة بشكل مباشر، لأنّها توفّر فقط الحد الأدنى من الوظائف التي يجب توسيعها لإتاحة استخدام القيم المتحركة بشكل كامل. أمّا الفئات الفرعية التالية، فتُكمّل Animator
:
الفئة | الوصف |
---|---|
ValueAnimator |
محرّك التوقيت الرئيسي لتحريك الخصائص، والذي يحتسب أيضًا قيم السمة المطلوب تحريكها. ويحتوي هذا النموذج على جميع الوظائف الأساسية التي تحتسب قيم الصور المتحركة، كما يحتوي على تفاصيل توقيت كل صورة متحركة، ومعلومات حول ما إذا كانت
الرسوم المتحركة تتكرر، وأدوات الاستجابة التي تتلقى أحداث التحديث، وإمكانية تحديد أنواع مخصصة للتقييم. هناك قسمان للخصائص المتحركة، هما: حساب القيم المتحركة وضبط هذه القيم على الكائن والخاصية التي يتم تحريكها. ولا ينفّذ ValueAnimator الجزء الثاني، لذا يجب أن تستمع
إلى التعديلات على القيم التي تحتسبها ValueAnimator ، وأن تعدّل العناصر التي تريد تحريكها وفقًا لمنطقك الخاص. راجِع القسم حول
الرسوم المتحركة باستخدام ValueAnimator للحصول على مزيد من المعلومات. |
ObjectAnimator |
هي فئة فرعية من ValueAnimator تتيح لك ضبط خاصية كائن وكائن هدف لتحريكها. وتُعدِّل هذه الفئة السمة وفقًا لذلك عندما
تحتسب قيمة جديدة للصورة المتحركة. ننصحك باستخدام
ObjectAnimator معظم الوقت
لأنّه يجعل عملية تحريك القيم المتحركة على العناصر المستهدفة أسهل كثيرًا. في المقابل،
قد تحتاج أحيانًا إلى استخدام السمة ValueAnimator مباشرةً لأنّ السمة ObjectAnimator تفرض بعض القيود الإضافية، مثل طلب توفّر
طرق وصول معيّنة في العنصر الهدف. |
AnimatorSet |
توفر آلية لتجميع الصور المتحركة معًا بحيث تعمل في ضوء بعضها البعض. يمكنك ضبط الصور المتحركة لتشغيلها معًا، أو بشكل تسلسلي، أو بعد مهلة محددة. للحصول على مزيد من المعلومات، يمكنك الاطّلاع على القسم حول تصميم صور متحركة متعددة باستخدام مجموعات الرسوم المتحركة. |
يُطلع المقيّمون نظام الصور المتحركة على كيفية احتساب قيم سمة معيّنة. وهي تستخدم بيانات التوقيت التي توفّرها الفئة Animator
، وهي قيمة بداية ونهاية الصورة المتحركة، وتحسب القيم المتحركة للسمة
بناءً على هذه البيانات. يوفر نظام الرسوم المتحركة للخصائص المقيّمين التاليين:
الصف/الواجهة | الوصف |
---|---|
IntEvaluator |
المقيِّم التلقائي لحساب قيم خصائص int . |
FloatEvaluator |
المقيِّم التلقائي لحساب قيم خصائص float . |
ArgbEvaluator |
المقيِّم التلقائي لحساب قيم خصائص اللون التي يتم تمثيلها كقيم سداسية عشرية. |
TypeEvaluator |
واجهة تسمح لك بإنشاء مقيّم خاص بك. إذا كنت تتحرك
خاصية عنصر ليست int أو float أو لون،
عليك تنفيذ واجهة TypeEvaluator لتحديد طريقة
احتساب القيم المتحركة لخاصية الكائن. يمكنك أيضًا تحديد سمة TypeEvaluator مخصّصة لقيم int وfloat واللون
إذا كنت تريد معالجة هذه الأنواع بطريقة مختلفة عن السلوك التلقائي.
راجِع القسم حول استخدام مُقيّم النوع للحصول على مزيد من المعلومات
حول كيفية كتابة مقيّم مخصّص. |
تحدّد أداة استيفاء الوقت كيفية احتساب قيم معيّنة في إحدى الصور المتحركة
كدالة للوقت. على سبيل المثال، يمكنك تحديد مؤثرات حركية لتنفيذها بشكل خطي في الصورة المتحركة بأكملها، أي أن الحركة تتحرك بالتساوي طوال الوقت، أو يمكنك تحديد حركات باستخدام زمن غير خطي، مثل تسريع الحركة في البداية والإبطاء في نهايتها. يوضّح الجدول 3 أدوات الاستيفاء المضمَّنة في android.view.animation
. إذا لم يلائم أيٌّ من هذه الأدوات احتياجاتك،
يمكنك تنفيذ واجهة TimeInterpolator
وإنشاء الواجهة الخاصة بك. راجِع استخدام أداة الاستيفاء للحصول على مزيد من المعلومات عن كيفية كتابة أداة مخصّصة.
الصف/الواجهة | الوصف |
---|---|
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 لمدة 1,000 ملي ثانية عند تشغيل طريقة 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
لمدة 1,000 ملي ثانية، عند تشغيل الإجراء 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 إلى الفئة إذا كان لديك الحق في القيام بذلك.
- استخدِم فئة برنامج تضمين لديك الحق في تغييرها واطلب من هذا البرنامج تلقّي القيمة باستخدام طريقة ضبط صالحة ثم أعِد توجيهها إلى الكائن الأصلي.
- يمكنك استخدام
ValueAnimator
كبديل.
- إذا حدّدت قيمة واحدة فقط للمعلَمة
values...
في إحدى طرق الإعدادات الأصلية لـObjectAnimator
، يُفترض أن تكون القيمة النهائية للصورة المتحركة. وبالتالي، يجب أن تحتوي خاصية الكائن التي تريد تحريكها على دالة getter التي تُستخدَم للحصول على القيمة الافتتاحية الخاصة بالحركة. يجب أن تكون دالة getter بالصيغةget<PropertyName>()
. على سبيل المثال، إذا كان اسم السمة هوfoo
، يجب استخدام طريقةgetFoo()
. - يجب أن تعمل طريقتا getter (إذا لزم الأمر) وsetter للسمة التي تريد إنشاء رسوم متحركة لها
بنفس نوع قيمتَي البداية والنهاية التي تحدِّدها للسمة
ObjectAnimator
. على سبيل المثال، يجب أن يتوفّر لديكtargetObject.setPropName(float)
وtargetObject.getPropName()
إذا أنشأت علامةObjectAnimator
التالية:ObjectAnimator.ofFloat(targetObject, "propName", 1f)
. - حسب الخاصية أو العنصر الذي تحرّكه، قد تحتاج إلى استدعاء طريقة
invalidate()
في أحد الملفات الشخصية لفرض إعادة رسم الشاشة باستخدام القيم المتحركة المعدّلة. يمكنك إجراء ذلك من خلالonAnimationUpdate()
. على سبيل المثال، عند تحريك خاصية اللون لكائن قابل للرسم، يتم تطبيق تعديلات على الشاشة فقط عندما يعيد ذلك الكائن رسمه. إنّ جميع ضبط السمات في الملف الشخصي، مثلsetAlpha()
وsetTranslationX()
، يؤدي إلى إبطال صلاحية العرض بشكلٍ صحيح، لذا لا تحتاج إلى إلغاء صلاحية العرض عند استدعاء هذه الطرق بقيم جديدة. لمزيد من المعلومات حول المستمعين، يمكنك الاطّلاع على القسم حول أدوات معالجة الصور المتحركة.
صمِّم صورًا متحركة متعددة باستخدام مجموعة AnimatorSet
في كثير من الأحيان، ستحتاج إلى تشغيل صورة متحركة تعتمد على وقت بدء صورة متحركة أخرى
أو انتهائها. يتيح لك نظام Android تجميع الصور المتحركة معًا في AnimatorSet
حتى تتمكّن من تحديد ما إذا كنت تريد بدء الصور المتحركة
في وقت واحد أو بشكل تسلسلي أو بعد مهلة محددة. يمكنك أيضًا دمج عناصر AnimatorSet
داخل بعضها.
يشغِّل مقتطف الرمز التالي كائنات Animator
التالية بالطريقة التالية:
- تشغيل
bounceAnim
. - يتم تشغيل
squashAnim1
وsquashAnim2
وstretchAnim1
وstretchAnim2
في الوقت نفسه. - تشغيل
bounceBackAnim
. - تشغيل
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()
على "ملف شخصي" لفرض إعادة رسم تلك المنطقة من الشاشة باستخدام القيم المتحركة الجديدة. على سبيل المثال، عند تحريك خاصية اللون لكائن قابل للرسم فقط، لا يتم إجراء تعديلات على الشاشة إلا عندما يعيد ذلك الكائن رسمه. جميع قيم السمات التي تضبطها في الملف الشخصي، مثلsetAlpha()
وsetTranslationX()
، تؤدي إلى إبطال صلاحية العرض بشكلٍ صحيح، لذا لا تحتاج إلى إلغاء صلاحية العرض عند استدعاء هذه الطرق بقيم جديدة.
-
يمكنك تمديد الفئة AnimatorListenerAdapter
بدلاً من تنفيذ الواجهة Animator.AnimatorListener
إذا لم تكن تريد تنفيذ جميع الطرق المستخدَمة في واجهة Animator.AnimatorListener
. توفّر الفئة 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، بالإضافة إلى توفير طريقة سهلة لتحريك عناصر View نفسها.
يمكنك إضافة تأثيرات حركية إلى تغييرات التنسيق داخل ViewGroup باستخدام
الفئة LayoutTransition
. يمكن أن تمر المشاهدات داخل مجموعة ViewGroup
بصورة متحرّكة تظهر وتختفي عند إضافتها إلى
مجموعة مشاهدة أو إزالتها منها أو عند طلب طريقة "setVisibility()
" للملف الشخصي باستخدام
VISIBLE
أو INVISIBLE
أو
GONE
. يمكن لطرق العرض المتبقية في ViewGroup
أيضًا إضافة تأثيرات حركية إلى مواضعها الجديدة عند إضافة مشاهدات أو إزالتها. يمكنك تحديد الرسوم المتحركة التالية في كائن 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" />
عند ضبط هذه السمة على "صحيح"، يتم تلقائيًا نقل الملفات الشخصية التي تتم إضافتها أو إزالتها من "مجموعة المشاهدة" وكذلك الملفات الشخصية المتبقية في "مجموعة المشاهدة".
تحريك تغييرات حالة العرض باستخدام StateListAnimator
تتيح لك الفئة StateListAnimator
تحديد أدوات الصور المتحركة التي يتم تشغيلها عندما تتغير حالة العرض. يعمل هذا الكائن كبرنامج تضمين لكائن Animator
، حيث يستدعي هذه الصورة المتحركة كلما تغيّرت حالة العرض المحدّدة (مثل "مضغوط" أو "مركّز").
يمكن تحديد StateListAnimator
في مورد XML باستخدام عنصر <selector>
جذر وعناصر <item>
ثانوية يحدّد كل منها حالة عرض مختلفة تحدّدها الفئة StateListAnimator
. وتحتوي كل سمة <item>
على تعريف مجموعة صور متحركة.
على سبيل المثال، يقوم الملف التالي بإنشاء قائمة حالة متحركة يقوم بتغيير المقياسين x وy للعرض عند الضغط عليهما:
<?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>
استخدام مُقيِّم النوع
إذا كنت تريد إضافة تأثيرات حركية إلى نوع غير معروف لنظام 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
في الحركة
ويحدث تباطؤًا خارجها. تحدّد الطرق التالية المنطق الذي تستند إليه هذه الأدوات:
AcccelerateDecelerateIntersolator
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; }
المقياس الخطي
Kotlin
override fun getInterpolation(input: Float): Float = input
Java
@Override public float getInterpolation(float input) { return input; }
يمثّل الجدول التالي القيم التقريبية التي تحتسبها أدوات الاستيفاء هذه لبيانات متحركة تستمر لمدة 1,000 ملي ثانية:
الدقائق المنقضية | الكسر المنقضي/الكسر المداخل (خطي) | الكسر المضلل (تسريع/تسريع) |
---|---|---|
0 | 0 | 0 |
200 | 2. | .1 |
400 | 4. | .345 |
600 | 6. | 8. |
800 | 8. | .9 |
1,000 | 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
: هما سمتان بسيطتان من الخدمات لوصف الموقع النهائي للعرض في حاويته، كمجموع القيمتين اليمنى والعلوية، وقيم الترجمة X والترجمة Y.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
في آن واحد لملف شخصي.
كائنات ObjectAnimator متعددة
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();
أداة One 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 التالية:
-
ValueAnimator
-<animator>
-
ObjectAnimator
-<objectAnimator>
-
AnimatorSet
-<set>
للعثور على السمات التي يمكنك استخدامها في بيان 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 لتحديد الصور المتحركة للخصائص، يمكنك الاطّلاع على موارد الصور المتحركة .
التأثيرات المحتملة على أداء واجهة المستخدم
تتسبب عوامل الرسوم المتحركة التي تقوم بتحديث واجهة المستخدم في إحداث عمل عرض إضافي لكل إطار يتم تشغيل الرسوم المتحركة فيه. لهذا السبب، يمكن أن يؤثر استخدام الرسوم المتحركة التي تستهلك قدرًا كبيرًا من الموارد سلبًا على أداء تطبيقك.
تتم إضافة العمل المطلوب لتحريك واجهة المستخدم إلى مرحلة الرسوم المتحركة في مسار العرض. يمكنك معرفة ما إذا كانت الرسوم المتحركة تؤثر في أداء تطبيقك أم لا من خلال تفعيل عرض وحدة معالجة الرسومات الملف الشخصي ومراقبة مرحلة الصور المتحركة. لمزيد من المعلومات، يُرجى الاطّلاع على جولة تفصيلية حول عرض وحدة معالجة الرسومات الملف الشخصي.