Посібник для початківців щодо впровадження анімації Android - Частина 1 (2 частини серії)

Зізнайтеся, ви завжди хотіли створювати візуально привабливі програми. Але завдяки функціональному підходу, анімація завжди була відкладена. Більше не.

Трохи основ про анімацію:

Існує 3 типи анімацій:

  1. Анімації властивостей - Вони використовуються для зміни властивостей об'єктів (перегляди або об'єкти, що не переглядаються). Ми визначаємо певні властивості (наприклад, translateX, TextScaleX) об'єктів, які потрібно змінити. Різні характеристики анімації, якою можна керувати, - це тривалість анімації, чи потрібно її реверсувати і скільки разів ми хочемо повторити анімацію тощо. Вони були введені в Android 3.0 (API рівня 11).
  2. Перегляд анімації - їх використовують для створення простих анімацій, таких як зміна розміру, положення, обертання, контроль прозорості. Їх легко побудувати і дуже швидко, але вони мають свої обмеження. Наприклад - їхній стан змінюється, але їхня власність не змінюється. Перегляд анімації буде висвітлено у частині 2.
  3. Анімації, що малюються - це використовується для анімації за допомогою малюнків. Створюється XML-файл із зазначенням різних списків малюнків, які запускаються одна за одною, як рулон плівки. Це не дуже використовується, тому я його не висвітлюю.
Android 5.0 представив різні інші анімації - ефект виявлення, переходи активності / фрагментів, переходи спільних елементів тощо. Клацніть тут, щоб дізнатися більше про це.
Примітка - Частина 1 обговорюватиме лише анімаційні властивості.

Коли використовувати який тип анімації

  1. Якщо ви просто хочете робити просту анімацію для переглядів, не обробляючи інші деталі, як-от торкніться чи клацніть, скористайтеся Переглянути анімації. Проблема з View Animations полягає в тому, що, хоча стан перегляду змінюється, його властивість все ще залишається у вихідному положенні. Це означає, що якщо ImageButton переміщено від 0 до 100 пікселів праворуч, хоча воно буде анімовано праворуч, натискання кнопки (властивості) зображення все ще буде на 0-му положенні.
  2. Перегляд анімацій можна використовувати на екранах заставки. Використовуючи Перегляд анімацій, використовуйте XML замість того, щоб це робити програмно. Використовуючи XML-файли, вона є більш читаною і може бути спільною між іншими переглядами.
  3. Якщо ви хочете керуватися дотиком, клацніть після анімації, перейдіть до анімації властивостей, оскільки вони змінюють стан, а також поведінку.

Концепції анімації власності

Всередині анімації власності. Надано Google.

Фактична анімація проводиться Value Animator. Цей клас відстежує тривалість анімації та поточне значення властивості, яке вона анімує. TimeInterpolater відстежує час (швидкість) анімації, наприклад, чи є вона з постійною швидкістю в заданий час, або прискорюється, а потім сповільнюється в даний час. TypeEvaluator використовується для обчислення дробів на основі типу TypeEvalutor, який використовується, наприклад, int, float, rgb тощо. Ми можемо використовувати користувальницький TypeEvaluator також, якщо жоден не відповідає нашим потребам.

Анімації, що використовують ValueAnimator

Клас ValueAnimator дозволяє анімувати значення певного типу протягом тривалості анімації, вказавши набір значень int, float або color для анімації. Ви отримуєте ValueAnimator, викликаючи один із його заводських методів: ofInt (), ofFloat () або ofObject (). Наприклад:

заключний TextView animteTextView = (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, "переклад Y", 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.

У своєму поточному проекті я зробив таку анімацію:

(Незабаром буде оновлено. Вибачте за незручності.)

Як ми бачимо, є кілька анімацій, які працюють одночасно. Триває одночасна анімація. Коли натискається значок пошуку, спочатку значок пошуку переміщується ліворуч, логотип згасає, кнопка скасування згасає, а редагування тексту також згасає. При натисканні кнопки скасувати відтворюється та ж анімація, але у зворотному напрямку.

Код для цього:

   --------- виконайте анімацію на значку пошуку, натисніть ----------
// піднятися в крайнє ліве положення
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, "альфа", 1f, 0f);
logoFadeOutAnimator.setDuration (SEARCH_ANIMATION_DURATION);

ObjectAnimator cancelImageFadeInAnimator = ObjectAnimator.ofFloat (mIvCancelSearch, "альфа", 0f, 1f);
cancelImageFadeInAnimator.setDuration (SEARCH_ANIMATION_DURATION);

ObjectAnimator searchEditTextAnimator = ObjectAnimator.ofFloat (mEtSearch, "альфа", 0f, 1f);
searchEditTextAnimator.setDuration (SEARCH_ANIMATION_DURATION);

AnimatorSet animatorSet = новий AnimatorSet ();
animatorSet.play (searchIconLeftAnimation) .with (logoFadeOutAnimator);
animatorSet.play (searchIconLeftAnimation) .with (cancelImageFadeInAnimator);
animatorSet.play (searchIconLeftAnimation) .with (searchEditTextAnimator);

animatorSet.start ();
   --------- повернути всі анімації при скасуванні натисніть ----------
ObjectAnimator searchIconRightAnimation = ObjectAnimator.ofFloat (mIvSearch, "translationX", 0);
searchIconRightAnimation.setDuration (SEARCH_ANIMATION_DURATION);

ObjectAnimator logoFadeInAnimator = ObjectAnimator.ofFloat (mAppLogo, "альфа", 0f, 1f);
logoFadeInAnimator.setDuration (SEARCH_ANIMATION_DURATION);

ObjectAnimator cancelImageFadeOutAnimator = ObjectAnimator.ofFloat (mIvCancelSearch, "альфа", 1f, 0f);
cancelImageFadeOutAnimator.setDuration (SEARCH_ANIMATION_DURATION);

ObjectAnimator searchEditTextFadeInAnimator = ObjectAnimator.ofFloat (mEtSearch, "альфа", 1f, 0f);
searchEditTextFadeInAnimator.setDuration (SEARCH_ANIMATION_DURATION);

AnimatorSet animatorSet = новий AnimatorSet ();
animatorSet.play (searchIconRightAnimation) .with (logoFadeInAnimator);
animatorSet.play (searchIconRightAnimation) .with (cancelImageFadeOutAnimator);
animatorSet.play (searchIconRightAnimation) .with (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);
     ---------------------------- VS --------------------- --------
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 мс? Чи є накладні виступи?

Аніматори, що оновлюють користувальницький інтерфейс, викликають додаткові роботи з рендерінгу для кожного кадру, в якому працює анімація. З цієї причини використання анімації, що інтенсивно використовує ресурси, може негативно вплинути на ефективність вашої програми.

Робота, необхідна для анімації вашого інтерфейсу, додається до етапу анімації конвеєра візуалізації. Ви можете дізнатися, чи впливає ваша анімація на ефективність вашої програми, включивши Програмування GPU-рендерінгу та відстежуючи етап анімації.

Подумайте про випадок використання, а потім застосуйте відповідний спосіб.

Дякуємо, що прочитали статтю. Пропозиції / виправлення / коментарі завжди вітаються. Якщо вам це подобається, натисніть кнопку "подобається" та поділіться статтею із спільнотою Android. Давайте поділимось знаннями, наскільки можемо.

Примітка. Частина 2 щодо ViewAnimations також найближчим часом.

Також давайте станемо друзями в About.me, Twitter, LinkedIn, Github та Facebook.