Анимация
Движение, которое показывает пользователю, что изменилось и куда что делось. Во Flutter анимация даётся настолько легко, что настоящее умение здесь — сдержанность и понимание, какой из нескольких API уместен.
Почему это важно. Хорошее движение делает интерфейс очевидным без единого слова подсказки. Плохое — слишком долгое, слишком пружинистое, запускающееся на каждой перестройке — заставляет приложение казаться медленным, даже когда оно быстрое, и виноватым пользователи считают приложение.
Что понимать
- Что именно объясняет движение и теряется ли что-нибудь без него
- Что меняется: значение, widget или целый экран
- Кто управляет анимацией и кто её освобождает
- Идёт ли она в UI-потоке или её можно отдать compositor
- Как она ведёт себя у того, кто попросил систему уменьшить движение
Основные темы
API, в порядке предпочтения
- Неявные —
AnimatedContainer,AnimatedOpacityи остальное семейство TweenAnimationBuilder— одно значение без контроллераAnimationController— всё, чем нужно управлять, что нужно выстроить в последовательность или проиграть назад- Явные переходы и
AnimatedBuilder, чтобы перестраивать как можно меньше - Движение по физике — там, где пружина лучше кривой
Как делать это хорошо
- Длительность и кривая; почему большинство анимаций слишком медленные
- Хореография: что движется вместе, а что — со сдвигом
- Прерываемость — разворот на полпути вместо резкого скачка
- Hero-переходы между экранами и случаи, когда они вводят в заблуждение
Цена
-
Перестройка поддерева на каждом кадре против перерисовки одного элемента
-
Трансформация и прозрачность дёшевы, изменения раскладки — нет
-
Подтормаживания на компиляции шейдеров и что изменил Impeller
-
Измерение через performance overlay, а не на глаз
Как делать это ответственно
- Уважение к системной настройке уменьшения движения
- Движение не должно нести информацию, которой нет больше нигде
- Не анимировать то, что пользователь пытается прочитать
Уровни
| Уровень | Как это выглядит |
|---|---|
| Junior | Использует неявные анимации, чтобы переходы не были резкими. |
| Middle | Управляет контроллерами, выстраивает движение в последовательности и со сдвигом, аккуратно освобождает ресурсы, держит перестройки узкими. |
| Senior | Проектирует движение как часть взаимодействия, делает его прерываемым и дешёвым, учитывает настройки доступности. |
Практика
Для начала
-
Замените скачок плавным появлением Найдите изменение состояния, которое происходит рывком, и превратите его в переход.
-
Сократите длительность вдвое Возьмите самую медленную свою анимацию и урезайте её, пока она не станет ощущаться отзывчивой, а не роскошной.
-
Освободите контроллер Найдите
AnimationControllerбезdisposeи почините утечку.
Дальше
-
Сделайте анимацию прерываемой Постройте анимацию, которая плавно разворачивается, когда пользователь передумал на полпути.
-
Запустите список со сдвигом Показывайте элементы со смещением по времени и удержите это дёшево на длинном списке.
-
Учтите уменьшение движения Прочитайте настройку доступности и предусмотрите путь без анимации.
Проверьте себя
- Какая анимация в вашем приложении самая длинная и оправдывает ли она это время?
- Что произойдёт, если пользователь нажмёт ещё раз, пока анимация идёт?
- Какие из ваших анимаций вызывают перестройку widget-ов вместо перерисовки?
- Что делает ваше приложение, когда система просит уменьшить движение?
- Где движение несёт информацию, которой нет больше нигде?
- Как вы докажете, что анимация пропускает кадры?
Материалы
- Introduction to animations — официальный обзор и, что важнее всего, схема выбора подходящего API.
- Animations tutorial —
контроллеры, tween-ы и
AnimatedBuilder, разобранные шаг за шагом, вместе с объяснением, зачем нужен каждый слой. - Material Design: Motion — рекомендации по длительностям и сглаживанию, выведенные из исследований, а не из вкуса. Самый быстрый способ перестать угадывать длительности.
- Flutter performance overlay — как увидеть, укладывается ли анимация в бюджет кадра.
- Building beautiful transitions with Material Motion — прикладная хореография, а не механика API — как раз то, чего обычно не хватает.