دليل المبتدئين لتطبيق الرسوم المتحركة لنظام أندرويد - الجزء الأول (سلسلة الجزء الثاني)

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

بعض الأساسيات حول الرسوم المتحركة:

هناك 3 أنواع من الرسوم المتحركة:

  1. الرسوم المتحركة للخصائص - يتم استخدامها لتغيير خاصية الكائنات (طرق العرض أو كائنات غير العرض). نحدد بعض الخصائص (مثل translateX ، TextScaleX) للكائنات المطلوب تغييرها. الخصائص المختلفة للرسوم المتحركة التي يمكن معالجتها هي مدة الرسوم المتحركة ، سواء كان عكسها أو كم مرة نريد تكرار الرسوم المتحركة وما إلى ذلك. تم تقديمها في Android 3.0 (API المستوى 11).
  2. عرض الرسوم المتحركة - يتم استخدامها للقيام بالرسوم المتحركة البسيطة مثل تغيير الحجم والموضع والدوران والتحكم في الشفافية. فهي سهلة البناء وسريعة للغاية ولكن لها قيود خاصة بها. على سبيل المثال - حالتهم تتغير لكن ممتلكاتهم لا تتغير. سيتم تغطية عرض الرسوم المتحركة في الجزء 2.
  3. الرسوم المتحركة Drawable - يستخدم هذا للقيام بالرسوم المتحركة باستخدام drawables. يتم إنشاء ملف XML يحدد قائمة متنوعة من الأدراج التي يتم تشغيلها واحدة تلو الأخرى مثل لفة فيلم. لا يستخدم هذا كثيرًا لذا لن أغطيه.
قدم Android 5.0 العديد من الرسوم المتحركة الأخرى - Reveal Effect ، نشاط / تجزئة التحولات ، انتقالات العنصر المشترك ، إلخ. انقر هنا لمعرفة المزيد حول هذا.
ملاحظة - الجزء الأول سيناقش الرسوم المتحركة للملكية فقط.

متى استخدام أي نوع من الرسوم المتحركة

  1. إذا كنت تريد فقط القيام برسومات متحركة بسيطة على طرق العرض دون الحاجة إلى التعامل مع تفاصيل أخرى مثل اللمس أو النقر ، استخدم عرض الرسوم المتحركة. تكمن مشكلة عرض الرسوم المتحركة في أنه على الرغم من تغير حالة العرض ، فإن ملكيته تظل في الموضع الأصلي. هذا يعني أنه إذا تم نقل ImageButton من 0 إلى 100 بكسل إلى اليمين ، على الرغم من أنه سيتم تحريكه إلى اليمين ، فستظل لمسة (خاصية) زر الصورة في الموضع 0.
  2. عرض الرسوم المتحركة يمكن استخدامها في شاشات سبلاش. عند استخدام عرض الرسوم المتحركة ، استخدم XML بدلاً من القيام بذلك برمجياً. باستخدام ملفات XML ، يكون أكثر قابلية للقراءة ويمكن مشاركته بين طرق العرض الأخرى.
  3. إذا كنت ترغب في التعامل مع اللمس ، انقر بعد الرسوم المتحركة ، اذهب إلى خاصية الرسوم المتحركة لأنها تغير الحالة وكذلك السلوك.

الرسوم المتحركة الملكية المفاهيم

داخل الرسوم المتحركة الملكية. من باب المجاملة جوجل.

الرسوم المتحركة الفعلية تتم بواسطة Value Animator. هذه الفئة تتعقب مدة الرسوم المتحركة والقيمة الحالية للممتلكات التي يتم تنشيطها. يتتبع TimeInterpolater الوقت (السرعة) للرسوم المتحركة مثل ما إذا كان ذلك مع سرعة ثابتة في وقت معين ، أو تسريع ثم تباطؤ في وقت معين. يستخدم TypeEvaluator لحساب الكسور بناءً على نوع TypeEvalutor المستخدم على سبيل المثال ، int ، float ، rgb ، إلخ. يمكننا استخدام TypeEvaluator مخصص أيضًا إذا كان لا شيء يتناسب مع احتياجاتنا.

الرسوم المتحركة باستخدام ValueAnimator

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

final TextView animateTextView = (TextView) findViewById (R.id.tv_animate)؛

ValueAnimator valueAnimator = ValueAnimator.ofFloat (0f، 500f)؛
valueAnimator.setInterpolator (جديد AccelerateDecelerateInterpolator ()) ؛ / / زيادة السرعة أولا ثم إنقاص
valueAnimator.setDuration (2000)؛
valueAnimator.addUpdateListener (جديد ValueAnimator.AnimatorUpdateListener () {
    @تجاوز
    public void onAnimationUpdate (ValueAnimator animation) {
        تقدم float = (float) animation.getAnimatedValue ()؛
        animateTextView.setTranslationY (التقدم)؛
        // لا حاجة لاستخدام invalidate () لأنه موجود بالفعل في // عرض النص.
    }
})؛
valueAnimator.start ()؛
من باب المجاملة Giphy

يمكن تحقيق نفس الشيء باستخدام كود XML على النحو التالي:

                   /res/animator/value_animator_ex.xml
<؟ xml version = "1.0" encoding = "utf-8"؟>
                     ---- كود النشاط ----
ValueAnimator valueAnimator = (ValueAnimator) AnimatorInflater.loadAnimator (
        هذا ، R.animator.value_animator_ex) ؛

valueAnimator.addUpdateListener (جديد ValueAnimator.AnimatorUpdateListener () {
    @تجاوز
    public void onAnimationUpdate (ValueAnimator animation) {
        تقدم float = (float) animation.getAnimatedValue ()؛
        animateTextView.setTranslationY (التقدم)؛
    }
})؛

valueAnimator.start ()؛

الرسوم المتحركة باستخدام ObjectAnimator

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

لنفس الرسوم المتحركة أعلاه ، يمكننا كتابة رمز ObjectAnimator على النحو التالي:

TextView animateTextView = (TextView) findViewById (R.id.tv_animate)؛

ObjectAnimator textViewAnimator = ObjectAnimator.ofFloat (animateTextView، "translationY"، 0f، 500f)؛
textViewAnimator.setDuration (2000)؛
textViewAnimator.setInterpolator (جديد AccelerateDecelerateInterpolator ()) ؛
textViewAnimator.start ()؛

كما نرى ، لم يكن علينا استخدام المستمع لتحديث موضع عرض النص لأن ذلك يتم بواسطة ObjectAnimator نفسه. الشيء الرئيسي هنا هو أن نرى "translationY" وهي الخاصية التي نريد أن نؤدي الرسوم المتحركة عليها. يجب أن تكون هذه خاصية محددة في android أو إذا كانت ملكًا لنا ، فيجب علينا تحديد طرق الوصول الخاصة بها ، مثل getter وطريقة setter.

يمكن تنفيذ نفس الشيء باستخدام XML على النحو التالي:

                /res/animator/object_animator_ex.xml
<؟ xml version = "1.0" encoding = "utf-8"؟>
                        ---- كود النشاط ----

TextView animateTextView = (TextView) findViewById (R.id.tv_animate)؛

ObjectAnimator textViewAnimator = (ObjectAnimator) AnimatorInflater.loadAnimator (AnimationActivity.this، R.animator.object_animator_ex)؛
textViewAnimator.setTarget (animateTextView)؛
textViewAnimator.start ()؛

القيام الرسوم المتحركة متعددة في وقت واحد

يمكننا أن نبدأ في تشغيل عدة ObjectAnimators في نفس الوقت ونفس الوقت للقيام بعمل رسوم متحركة متعددة ، ولكنها ليست فعالة حيث لا توجد طريقة عرض تعرفها عن أي طريقة عرض أخرى. للقيام بنفس الشيء يمكننا استخدام فئة AnimatorSet.

في مشروعي الحالي ، قمت بالرسوم المتحركة التالية:

(سيتم تحديثه قريبًا. نأسف للإزعاج.)

كما نرى ، هناك رسوم متحركة متعددة تعمل في نفس الوقت. هناك 4 رسوم متحركة متزامنة. عند النقر على أيقونة البحث ، أولاً ، تتحرك أيقونة البحث إلى اليسار ، يتلاشى الشعار ، يتلاشى زر الإلغاء ويتلاشى النص أيضًا. عند النقر فوق زر "إلغاء" ، يتم تشغيل نفس الرسوم المتحركة ولكن في الاتجاه المعاكس.

الكود للقيام بذلك هو:

   --------- أداء الرسوم المتحركة على أيقونة البحث انقر ----------
// تأخذ إلى أقصى اليسار الموقف
DisplayMetrics displayMetrics = getResources (). getDisplayMetrics ()؛
int modifierX = - (displayMetrics.widthPixels - v.getWidth ())؛
نهائي ثابت خاص SEARCH_ANIMATION_DURATION = 1000 ؛ // 1 ثانية
ObjectAnimator searchIconLeftAnimation = ObjectAnimator.ofFloat (v، "translationX"، modifierX)؛
searchIconLeftAnimation.setDuration (SEARCH_ANIMATION_DURATION)؛

ObjectAnimator logoFadeOutAnimator = ObjectAnimator.ofFloat (mAppLogo، "alpha"، 1f، 0f)؛
logoFadeOutAnimator.setDuration (SEARCH_ANIMATION_DURATION)؛

ObjectAnimator deleteImageFadeInAnimator = ObjectAnimator.ofFloat (mIvCancelSearch، "alpha"، 0f، 1f)؛
cancelImageFadeInAnimator.setDuration (SEARCH_ANIMATION_DURATION)؛

ObjectAnimator searchEditTextAnimator = ObjectAnimator.ofFloat (mEtSearch، "alpha"، 0f، 1f)؛
searchEditTextAnimator.setDuration (SEARCH_ANIMATION_DURATION)؛

AnimatorSet animatorSet = جديد AnimatorSet ()؛
animatorSet.play (searchIconLeftAnimation). مع (logoFadeOutAnimator)؛
animatorSet.play (searchIconLeftAnimation). مع (cancelImageFadeInAnimator)؛
animatorSet.play (searchIconLeftAnimation). مع (searchEditTextAnimator)؛

animatorSet.start ()؛
   --------- عكس جميع الرسوم المتحركة على إلغاء انقر ----------
ObjectAnimator searchIconRightAnimation = ObjectAnimator.ofFloat (mIvSearch، "translationX"، 0)؛
searchIconRightAnimation.setDuration (SEARCH_ANIMATION_DURATION)؛

ObjectAnimator logoFadeInAnimator = ObjectAnimator.ofFloat (mAppLogo، "alpha"، 0f، 1f)؛
logoFadeInAnimator.setDuration (SEARCH_ANIMATION_DURATION)؛

ObjectAnimator deleteImageFadeOutAnimator = ObjectAnimator.ofFloat (mIvCancelSearch، "alpha"، 1f، 0f)؛
cancelImageFadeOutAnimator.setDuration (SEARCH_ANIMATION_DURATION)؛

ObjectAnimator searchEditTextFadeInAnimator = ObjectAnimator.ofFloat (mEtSearch، "alpha"، 1f، 0f)؛
searchEditTextFadeInAnimator.setDuration (SEARCH_ANIMATION_DURATION)؛

AnimatorSet animatorSet = جديد AnimatorSet ()؛
animatorSet.play (searchIconRightAnimation). مع (logoFadeInAnimator)؛
animatorSet.play (searchIconRightAnimation). مع (cancelImageFadeOutAnimator)؛
animatorSet.play (searchIconRightAnimation). مع (searchEditTextFadeInAnimator)؛

animatorSet.start ()؛

هنا أنشأنا العديد من كائنات الرسوم المتحركة على طرق عرض مختلفة وقمنا بلعبها معًا باستخدام AnimatorSet. أساليب مثل play () و with () تساعد على تحقيق ذلك.

يمكننا أيضًا استخدام المستمعين لتحديد حالة الرسوم المتحركة. على سبيل المثال:

animatorSet.addListener (جديد Animator.AnimatorListener () {
    @تجاوز
    public void onAnimationStart (الرسوم المتحركة المتحركة) {
        / / قم بأي شيء قبل بدء الرسوم المتحركة
    }

    @تجاوز
    public void onAnimationEnd (Animator animation) {
       / / قم بأشياء أخرى بعد انتهاء الرسوم المتحركة
    }

    @تجاوز
    public void onAnimationCancel (الرسوم المتحركة المتحركة) {
      / / قم بعمل شيء ما عندما يتم إلغاء الرسوم المتحركة (بواسطة المستخدم / المطور)
    }

    @تجاوز
    public void onAnimationRepeat (رسوم متحركة للرسوم المتحركة) {
       / / قم بعمل شيء ما عندما تتكرر الرسوم المتحركة
    }
})؛

عند تنفيذ العديد من الرسوم المتحركة على عرض واحد

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

. animateTextView.animate () دوران (360f) .y (500F) .setDuration (2000)؛
     ----------------------------ضد--------------------- --------
ObjectAnimator rotationAnimator = ObjectAnimator.ofFloat (animateTextView، "rotation"، 360f)؛
rotationAnimator.setDuration (2000)؛
ObjectAnimator translateAnimator = ObjectAnimator.ofFloat (animateTextView، "translationY"، 500f)؛
translateAnimator.setDuration (2000)؛
AnimatorSet set = جديد AnimatorSet ()؛
set.playTogether (rotationAnimator، translateAnimator)؛
ضبط بداية التشغيل()؛

هل الرسوم المتحركة تجعل تطبيقي بطيئًا أم أنها ستتخطى فترة 16ms لرسم الوقت؟ هل هناك أي النفقات العامة على الأداء؟

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

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

فكر في حالة الاستخدام ثم قم بتطبيق الطريقة المناسبة.

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

ملاحظة - الجزء 2 على ViewAnimations قريبًا أيضًا.

أيضًا ، لنصبح أصدقاء على About.me و Twitter و LinkedIn و Github و Facebook.