What is transition animation android

Animate all the things. Transitions in Android

May 19, 2016 · 7 min read

Hey, Android Developer. I would like to tell you something new about animations. Google finally made a statement with Material Design: animations are not only for iOS. Part of the new concept is Material motion.

“Motion provides meaning. Objects are presented to the user without breaking the continuity of experience even as they transform and reorganize. Motion in the world of material design is used to describe spatial relationships, functionality, and intention with beauty and fluidity.”
— Material Design guidelines.

In fact, the process of creating animations takes time. It’s sure tempting to just call setVisibility(View.VISIBLE) and move on to business logic of your awesome new feature, given that it’s already past all deadlines. But remember: every time you ignore opportunity to add meaningful UI transition another sad designer appears somewhere in the world.

What if I t o ld you that animations require less effort than you think? Have you ever heard about Transitions API? Yes, it is that thing promoted by Google for fancy animations between Activities. Sadly, it is available only starting from Android 5.0. So no one is actually using it. But imagine that this API can be efficiently used in many different cases and, what’s even more exciting, available on older Android versions.

Let’s start with some history

New animateLayoutChange parameter was introduced for ViewGroup in Android 4.0. But even with calling getLayoutTransition() and configuring some stuff inside it, it was still unstable and not flexible enough. So you couldn’t do much with it.

Version 4.4 Kitkat brings us idea of Scenes and Transitions. Scene is technically the state of all views in our Scene root (layout container). Transition is the set of Animators which will be applied for the view to perform smooth transition from the one scene to another. Will it be more fascinating with the examples? Yeah.

Imagine we have a button

After a click we want to have a text appeared below the button. Here is our layout:

And in Java we have a click listener:

Not bad. Animations with just one line of code. What’s interesting here is that not only the text visibility was animated, but also a button position. The Transition framework automatically animates layout change caused by appearance of TextView, so you don’t have to do it by yourself. You can even start new animation while old one is still running. The Transition framework will stop animation in progress and then continue to animate views from their current position. All under the hood, automagically.

We can specify the exact Transition types that will be applied via the second parameter of beginDelayedTransition method.

Simple types of Transition

  • ChangeBounds. It animates changes to view position and size. This one moves the button in our example.
  • Fade. It extends Visibility class and performs most popular animations — fade in and fade out. In example it’s applied to TextView.
  • TransitionSet. It’s Transition that is actually a set of another Transitions. They can be started together or sequential, to change it call setOrdering.
  • AutoTransition. It’s TransitionSet that contains Fade out, ChangeBounds and Fade in in sequential order. At first, views that don’t exist in the second scene are faded out, then change bounds applied for changes of position and size, and, finally, new views appear with fade in. AutoTransition used by default when you don’t specify any transition in the second argument of beginDelayedTransition.
Читайте также:  Зимний пейзаж для андроид

Backport

Everyone wants to write only one implementation that will have consistent behaviour on every Android version. Hopefully, we can achieve that while still using Transitions API. Some time ago I had found two quite similar backport libraries on githab, but they are no longer maintained and both of them missed some things that still could be backported. So, I’ve created my own library based on both of them and added a lot of new stuff for compatibility with older Android versions. All API changes from Lollipop and Marshmallow have been merged too.

So, there we have it: Transitions Everywhere is a backport of Transitions API for Android 4.0 and above. To start using it just specify gradle dependency:

And for all related classes replace import from android.transition.* to com.transitionseverywhere.*

Google has released Support Library for Transitions framework, but it still contains some bugs fixed in my library. I wrote an article to compare them. Please check it out.

What else we can do

First of all, we can change duration, interpolator and start delay for animators inside Transition:

Let’s have a look at other Transition types available.

Slide

Like Fade transition, extends Visibility class. It helps new view in scene to slide in from one of the sides. Example with Slide(Gravity.RIGHT):

Explode and Propagation

Explode is a lot like the Slide, but the view will slide in some calculated direction depending on a Transition epicenter (you should provide it with setEpicenterCallback method).

TransitionPropagation calculates start delays for each animators. For example, Explode use CircularPropagation by default. Delay for animation depends on distance between view and epicenter. To apply it, call setPropagation in Transition.

Let’s say, we have RecyclerView with GridLayoutManager and we want to remove all elements after a tap on any specific element. Like this:

ChangeImageTransform

ChangeImageTransform. Will animate changes of image matrix. It’s useful for situations when we change scaleType of ImageView. In most cases you’ll want to use it in pair with ChangeBounds to animate position, size and scaleType changes.

Path (Curved) motion

“Real-world forces, like gravity, inspire an element’s movement along an arc rather than in a straight line.”
— Material Design guidelines.

For every Transition that operates with two dimension coordinates (for example change of view position with ChangeBounds) we can apply curved motion with setPathMotion method.

TransitionName

Let say we need to remove all views from container and add the new set of views. And some of the new elements are actually the same as they were before recreating. How we can help framework to understand which items were removed and which elements were moved to a new position? Easy. Just call static method TransitionManager. setTransitionName(View v, String transitionName) to provide any unique name depending on your data model for every view.

For example if we want to create a list of the titles, and shuffle it with recreating views on every click of the button.

Scale

This one is not actually a part of Transitions API and was added by me. It allows us to animate visibility change with scale animation. Simple example with new Scale():

Also can be used in combination with other transitions, for example, Fade. We can put in constructor custom final scale:

Recolor

Try to figure out what this one is for. Exactly! Animated change of background and/or text color.

Источник

Создание анимаций переходов между Activity в Android

Начиная с Android 4.4 в арсенале разработчиков появился дополнительный инструмент для создания анимаций — Transitions Framework. Изначально он предназначался для создания анимаций изменения состояния приложения путём манипулирования несколькими View. С выходом Android 5.0 набор доступных для использования анимаций был расширен, чтобы соответствовать представленной тогда же концепции Material Design.

Читайте также:  Когда выйдет андроид 11 для realme c3

Transitions Framework позволяет быстро и безболезненно создавать различные анимации. Поэтому в процессе работы над iFunny было невозможно пройти мимо этого инструментария. Вниманию читателей предлагается частный случай использования Transitions API — создание анимации перехода между Activity с эффектом «бесшовности».

С визуальной точки зрения представленные в Transitions Framework анимации переходов между Activity можно условно разделить на два типа: обычные анимации и анимации с общим элементом. Концепт анимации с общим элементом продемонстрирован на честно украденном с сайта developer.android.com рис. 1. На нём в роли общих элементов выступают аватар и имя контакта.

Рис. 1. Анимация перехода между Activity с общими элементами

Но никто не любит длинные вступления, поэтому сразу перейдём к рассказу о том, как создавались анимации данного типа в приложении iFunny. В качестве первого примера рассмотрим анимацию, показанную на рис. 2. Для её использования нам потребуется Android версии 5.0 и выше.

Рис. 2. Анимация перехода между Activity на экране аутентификации пользователя

С точки зрения пользователя, здесь нет ничего необычного: один экран, простенькая анимация. Но, как вы уже могли догадаться, «под капотом» — переход между двумя экранами с одним общим элементом.

Первым шагом к созданию подобного перехода является, как ни странно, выбор этого самого элемента и определение его местоположения в вёрстке обеих Activity. После этого в описание каждого View, отображающего выбранный элемент, нужно добавить атрибут android:transitionName, а также назначить им android:id, если таковой отсутствует.

В нашем случае это обычные ImageView следующего вида:

Здесь стоит отметить два важных момента. Во-первых, в обоих ImageView необходимо установить одинаковые transitionName, что логично. Во-вторых, коль скоро мы используем ImageView, то и содержимое у них должно быть одним и тем же, поскольку использование двух отличающихся ресурсов может привести к неожиданным последствиям (как минимум к морганию анимируемого View в начале и конце анимации).

На втором шаге необходимо добавить опции для запускаемой (второй) Activity, сообщающие о том, что при её запуске должна быть запущена анимация.

Примечание. Под «второй» подразумевается запускаемая Activity, переход к которой должен быть осуществлён, а под «первой» — запускающая Activity.

Делается это следующим образом:

В приведённом листинге:

  • R.id.auth_logo — ImageView из первой Activity, используемый в анимации;
  • activity — первая Activity;
  • R.string.email_auth_transition — метка, ранее оставленная в вёрстке обоих ImageView;
  • SecondActivity.class — вторая Activity.

И сейчас внимательный читатель может испытать недоумение: во вступлении речь шла об использовании API level 19, в примере фигурировал API level 21, а в листинге выше стоит ограничение на API level 22. К сожалению, при написании кода выяснилось, что анимации перехода с общим элементом могут вести себя некорректно на телефонах c API level 21. Проявляется это в виде подтормаживаний анимации в целом и артефактов на анимируемом View в частности. Если вы уже знакомы с темой, знаете причины подобного поведения и/или способы решения описанной проблемы — расскажите нам об этом в комментариях.

На третьем шаге необходимо описать анимацию перехода, т.е. указать путь, проходимый анимируемым View, и трансформацию самого View. Для этого создадим отдельный файл projectName/src/main/res/transitions/email_auth_transition.xml со следующим содержимым:

Немного теории. Тег transitionSet предназначен для описания сразу нескольких трансформаций, применяемых к анимируемому View. Параметр transitionOrdering отвечает за порядок применения этих трансформаций. В нашем случае они применяются одновременно. Существует несколько типов готовых трансформаций, представленных в Transitions Framework. С полным списком можно ознакомиться на этой странице. Мы же остановимся на двух конкретных: changeBounds и changeImageTransform.

Первая предназначена для трансформации размера View. Вторая работает только с ImageView и в связке с первой позволяет изменять не только размер, но и форму ImageView. Использовав данные трансформации, получаем на выходе анимацию изменения размера изображения, представленную на рис. 2. Если не указывать тип движения анимируемого View, то он будет двигаться по кратчайшему пути. Более интересный способ передвижения рассмотрим во втором примере.

Читайте также:  Сейф файлов для андроида

Последним шагом создания анимации является её объявление в темах обеих Activity. Для этого отредактируем описание тем следующим образом (или создадим новые в папке projectName/src/main/res/values-v22/theme.xml):

  • android:windowActivityTransitions разрешает выполнение анимации перехода;
  • android:windowSharedElementEnterTransition указывает на файл с описанием анимации перехода от первой Activity ко второй;
  • android:windowSharedElementExitTransition указывает на файл с описанием анимации перехода при возвращении из второй Activity в первую.

Следует отметить, что для версий ОС ниже 5.1 необходимо создать темы с идентичными стилями, чтобы избежать вполне ожидаемых последствий в виде падения приложения. Например, поместим их в файл projectName/src/main/res/values/theme.xml:

Итак, для создания анимации перехода от Activity к Activity необходимо:

  1. Описать анимации (в нашем случае в xml-файле);
  2. Добавить эти анимации в xml-описание темы Activity;
  3. Пометить анимируемый общий элемент (View) в разметке;
  4. При запуске второй Activity указать в параметрах запуска, что для неё необходимо задействовать анимацию перехода.

Как видите, создавать такие анимации совсем не трудно, если не считать некоторых ограничений, упомянутых в первом примере. Теперь рассмотрим второй, более сложный пример. Тут нас интересует переход из раздела комментариев к профилю пользователя (рис. 3).

Рис. 3. Анимация перехода из комментариев к профилю пользователя

Все шаги по созданию перехода, рассмотренные выше, также подходят для этой анимации. А вот трансформация общего элемента реализована немного иначе. В приведённом ниже листинге описано перемещение общего элемента «по дуге» вместе с изменением его размера.

В чём же сложность второго примера? В первом случае использовалось изображение из ресурсов самого приложения, а тут — картинка загружается из сети. К тому же для комментариев изображение аватара пользователя берётся в более низком разрешении, чем для профиля. Поэтому требуется не только дать второй Activity доступ к изображению, используемому в первой, но и по завершении анимации подгрузить требуемое изображение в более высоком качестве. Так и получается две проблемы.

Для решения первой можно было бы собственноручно закэшировать изображение на диск или же передать его адрес в параметре второй Activity. Однако решение данной проблемы переложили на используемую в приложении библиотеку для загрузки изображений — Glide. При загрузке изображения достаточно просто добавить параметр diskCacheStrategy(DiskCacheStrategy.SOURCE), и оно будет закэшировано самой библиотекой (актуально для Glide версии 3.x). Следовательно, при повторном обращении к данному ресурсу из второй Activity будет использоваться кэшированный файл, что поможет нам избежать моргания анимируемого ImageView.

Вторая проблема также решается достаточно просто. В то время как осуществляется анимация перехода, профиль пользователя вместе с аватаром в более высоком разрешении скачиваются из сети и ожидают её завершения. Как только выполняются оба условия (завершение анимации и завершение загрузки), аватар пользователя обновляется. Добиться такого поведения можно, если использовать специальный Listener, в котором реализованы колбэки, вызываемые при смене статуса анимации. Для этого во Fragment, который принадлежит второй Activity, зададим этот самый Listener:

Здесь происходит следующее:

  1. С помощью getSharedElementEnterTransition().addListener() задаётся Listener для анимации появления Activity;
  2. В методе setAvatar() производится попытка загрузки и установки аватара (который уже лежит в кэше).

Рассмотрим, как именно реализован Listener:

В методе onProfileUpdated() мы обновляем содержимое профиля, в т.ч. и аватар.

Стоит отдельно упомянуть случай, когда общий элемент уходит за пределы экрана. Особенность его состоит в том, что, вопреки (а может, и согласно) логике, анимация перехода всё равно будет выполнена и будет смотреться достаточно забавно (рис. 4).

Рис. 4. Анимация возвращения из профиля в комментарии

Чтобы избежать подобного поведения, достаточно в момент ухода общего элемента за пределы экрана выставить ему видимость, отличную от View.VISIBLE.

В целом можно сказать, что Transitions Framework является простым и мощным инструментом для создания анимаций. Он не ограничивается только анимациями перехода между Activity — в статье был рассмотрен лишь частный случай его использования. Также стоит отметить, что помимо предоставляемых трансформаций имеется возможность создавать свои собственные, но это уже совсем другая история, достойная отдельного поста.

Источник

Оцените статью