Ръководство за начинаещи за прилагане на Android анимации - Част 1 (2 серии серия)

Признайте, винаги сте искали да създавате визуално привлекателни приложения. Но поради първия функционален подход, анимациите винаги бяха отлагани. Вече не.

Малко основи за анимациите:

Има 3 вида анимации:

  1. Анимации на собствеността - Те се използват за промяна на свойствата на обектите (изгледи или обекти без изглед). Ние определяме определени свойства (като translateX, TextScaleX) на обектите, които трябва да промените. Различни характеристики на анимацията, която може да се манипулира, е продължителността на анимацията, дали да я обърнем и колко пъти искаме да повторим анимацията и т.н. Те бяха въведени в Android 3.0 (API ниво 11).
  2. Преглед на анимации - Използват се за извършване на прости анимации като промяна на размера, позицията, въртенето, контролиране на прозрачността. Те са лесни за изграждане и са много бързи, но имат свои собствени ограничения. Например - Състоянието им се променя, но имуществото им не се променя. Преглед на анимации ще бъде разгледан в част 2.
  3. Чертожни анимации - Използва се за анимация с помощта на чертежи. Прави се XML файл, указващ различни списъци на чертежи, които се изпълняват един по един, точно като ролка от филм. Това не се използва много, така че няма да го покрия.
Android 5.0 представи различни други анимации - Reveal Effect, Преход на активност / фрагменти, преходи на споделен елемент и т.н. Кликнете тук, за да научите повече за това.
Забележка - Част 1 ще обсъжда само анимации на имоти.

Кога да използвате кой тип анимация

  1. Ако просто искате да правите прости анимации на изгледи, без да се налага да обработвате други детайли като докосване или щракване, използвайте View Animations. Проблемът с View Animations е, че въпреки че състоянието на View се променя, неговото свойство все още остава в първоначалната позиция. Това означава, че ако ImageButton бъде преместен от 0 до 100 пиксела вдясно, въпреки че ще анимира надясно, докосването (свойството) на бутона за изображение ще остане на 0-та позиция.
  2. Преглед на анимации може да се използва в екрани за пръскане. Когато използвате View Animations, използвайте XML, вместо да го правите програмно. Използвайки XML файлове, той е по-четим и може да бъде споделен между други изгледи.
  3. Ако искате да се справите с докосване, щракнете след анимацията, отидете за Property Animation, тъй като те променят състоянието, както и поведението.

Концепции за анимация на собственост

Вътре в анимацията на собствеността. С любезното съдействие на Google.

Действителната анимация се извършва от Value Animator. Този клас следи продължителността на анимацията и текущата стойност на свойството, което анимира. TimeInterpolater следи за времето (скоростта) на анимацията, например дали е с постоянна скорост в даденото време, или ускорява, след което се забавя в даденото време. TypeEvaluator се използва за изчисляване на дроби въз основа на типа TypeEvalutor, използван за например, int, float, rgb и т.н. Можем да използваме персонализиран TypeEvaluator също ако никой не отговаря на нашите нужди.

Анимации, използващи ValueAnimator

Класът ValueAnimator ви позволява да анимирате стойности от определен тип за продължителността на анимацията, като посочвате набор от стойности за int, float или цвят, чрез които да анимирате. Получавате 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 () {
    @Override
    public void onAnimationUpdate (ValueAnimator анимация) {
        float progress = (float) animation.getAnimatedValue ();
        animateTextView.setTranslationY (напредък);
        // няма нужда да използвате invalidate (), тъй като вече е налице в // текстовия изглед.
    }
});
valueAnimator.start ();
С любезното съдействие на Гифи

Същото може да се постигне с помощта на XML код, както следва:

                   /res/animator/value_animator_ex.xml

                     ---- Код на дейността ----
ValueAnimator valueAnimator = (ValueAnimator) AnimatorInflater.loadAnimator (
        това, R.animator.value_animator_ex);

valueAnimator.addUpdateListener (нов ValueAnimator.AnimatorUpdateListener () {
    @Override
    public void onAnimationUpdate (ValueAnimator анимация) {
        float progress = (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

                        ---- Код на дейността ----

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 ());
частен статичен краен int SEARCH_ANIMATION_DURATION = 1000; // 1 секунда
ObjectAnimator searchIconLeftAnimation = ObjectAnimator.ofFloat (v, "translationX", модификаторX);
searchIconLeftAnimation.setDuration (SEARCH_ANIMATION_DURATION);

ObjectAnimator logoFadeOutAnimator = ObjectAnimator.ofFloat (mAppLogo, "alpha", 1f, 0f);
logoFadeOutAnimator.setDuration (SEARCH_ANIMATION_DURATION);

ObjectAnimator cancelImageFadeInAnimator = 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 cancelImageFadeOutAnimator = 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 () {
    @Override
    публична невалидност onAnimationStart (анимация аниматор) {
        // направете нещо, преди да започне анимацията
    }

    @Override
    обществена невалидност onAnimationEnd (анимация на аниматора) {
       // правете други неща след приключване на анимацията
    }

    @Override
    публична невалидност onAnimationCancel (анимация аниматор) {
      // направете нещо, когато анимацията е отменена (от потребител / разработчик)
    }

    @Override
    публична невалидност onAnimationRepeat (анимация аниматор) {
       // направете нещо, когато анимацията се повтаря
    }
});

При извършване на множество анимации в един изглед

До сега сме виждали анимации на различни обекти на изглед. Можем да изпълняваме няколко анимации на един изглед, като използваме и горните подходи (използвайки аниматорски набор), но това е режийни резултати, тъй като има режийни разходи за настройка на AnimatorSet и работа на два аниматора паралелно. По-добър подход е да използвате ViewPropertyAnimator. Използвайки това, кодът е по-прост и за четене. Например:

. AnimateTextView.animate () въртене (360f) .y (500F) .setDuration (2000);
     ----------------------------СРЕЩУ--------------------- --------
ObjectAnimator rotationAnimator = ObjectAnimator.ofFloat (animateTextView, "въртене", 360f);
rotationAnimator.setDuration (2000);
ObjectAnimator translateAnimator = ObjectAnimator.ofFloat (animateTextView, "translationY", 500f);
translateAnimator.setDuration (2000);
Комплект AnimatorSet = нов AnimatorSet ();
set.playTogether (rotationAnimator, translateAnimator);
set.start ();

Анимацията прави ли приложението ми бавно или ще надмине времето на прозореца за теглене от 16 ms? Има ли някакви режийни разходи по представянето?

Аниматорите, които актуализират потребителския интерфейс, причиняват допълнителна работа за изобразяване за всеки кадър, в който работи анимацията. Поради тази причина използването на интензивни анимации с ресурси може да повлияе негативно на производителността на приложението ви.

Работата, необходима за анимиране на вашия потребителски интерфейс, се добавя към анимационния етап на тръбопровода за изобразяване. Можете да разберете дали вашите анимации влияят на производителността на приложението ви, като активирате Profile GPU Rendering и следите етапа на анимация.

Помислете за случая с употребата и след това приложите подходящия начин.

Благодаря, че прочетохте статията. Предложения / корекции / коментари винаги са добре дошли. Ако ви харесва, моля натиснете бутона за харесване и споделете статията с общността на Android. Нека споделяме знанията, колкото можем.

Забележка - Част 2 за ViewAnimations също идва съвсем скоро.

Също така, нека станем приятели в About.me, Twitter, LinkedIn, Github и Facebook.