- Определение настраиваемой анимации
- Содержание этого урока
- См. также
- Настройка реакции на касание
- Применение эффекта появления
- Настройка переходов
- Определение настраиваемых переходов
- Запуск операции с помощью переходов
- Запуск операции с помощью общего элемента
- Запуск операции с несколькими общими элементами
- Использование перемещения по кривой
- Анимация изменений состояния представления
- Анимация векторных элементов
Определение настраиваемой анимации
Содержание этого урока
- Настройка реакции на касание
- Применение эффекта появления
- Настройка переходов
- Анимация изменений состояния представления
- Анимация векторных элементов
См. также
Благодаря анимациям в Material Design пользователи получают отклик на выполняемые действия. Кроме того, анимации обеспечивают зрительную связь при взаимодействии с приложением. Тема Material Design содержит ряд анимаций по умолчанию для кнопок и переходов, а в Android 5.0 (уровень API 21) и более поздних версиях можно настраивать эти анимации и создавать новые:
- реакция на касание;
- круговое появление;
- переходы;
- перемещение по кривой;
- изменение состояний представления.
Настройка реакции на касание
Реакция на касание в Material Design обеспечивает моментальное визуальное подтверждение взаимодействия пользователя с элементами интерфейса в точке касания. В стандартной анимации для реакции на нажатие кнопок используется новый класс RippleDrawable
, обеспечивающий переход между разными состояниями с созданием эффекта ряби.
В большинстве случаев эту возможность следует применять в XML-файле представления, указав фон представления следующим образом:
?android:attr/selectableItemBackground
для ограниченной области ряби;?android:attr/selectableItemBackgroundBorderless
для ряби, распространяемой за границы представления. При отрисовке она будет ограничиваться ближайшим родительским элементом представления со значением фона, отличным от null.
Примечание. selectableItemBackgroundBorderless
— это новый атрибут, представленный в уровне API 21.
Также можно определить RippleDrawable
в качестве XML-ресурса с помощью элемента ripple
.
Можно назначить цвет для объектов RippleDrawable
. Чтобы изменить стандартный цвет отклика на касание, воспользуйтесь атрибутом темы android:colorControlHighlight
.
Дополнительные сведения представлены в справке по API для класса RippleDrawable
.
Применение эффекта появления
Анимация эффекта появления обеспечивает зрительную связь с действиями пользователя, когда отображается или скрывается группа элементов интерфейса. С помощью методаViewAnimationUtils.createCircularReveal()
можно анимировать ограничивающий круг, чтобы отобразить или скрыть с экрана представление.
Как отобразить ранее скрытое представление с помощью этого эффекта:
// previously invisible view View myView = findViewById(R.id.my_view); // get the center for the clipping circle int cx = (myView.getLeft() + myView.getRight()) / 2; int cy = (myView.getTop() + myView.getBottom()) / 2; // get the final radius for the clipping circle int finalRadius = Math.max(myView.getWidth(), myView.getHeight()); // create the animator for this view (the start radius is zero) Animator anim = ViewAnimationUtils.createCircularReveal(myView, cx, cy, 0, finalRadius); // make the view visible and start the animation myView.setVisibility(View.VISIBLE); anim.start();
Как скрыть ранее отображавшееся представление с помощью этого эффекта:
// previously visible view final View myView = findViewById(R.id.my_view); // get the center for the clipping circle int cx = (myView.getLeft() + myView.getRight()) / 2; int cy = (myView.getTop() + myView.getBottom()) / 2; // get the initial radius for the clipping circle int initialRadius = myView.getWidth(); // create the animation (the final radius is zero) Animator anim = ViewAnimationUtils.createCircularReveal(myView, cx, cy, initialRadius, 0); // make the view invisible when the animation is done anim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); myView.setVisibility(View.INVISIBLE); } }); // start the animation anim.start();
Настройка переходов
Переходы в приложениях Material Design обеспечивают зрительные связи между различными состояниями путем движения элементов и преобразований между общими элементами. Можно выбрать настраиваемые анимации для начальных и конечных переходов, а также для переходов общих элементов между операциями.
- Начальный переход определяет порядок появления на экране представлений в операции. Например, в начальном переходе explode представления появляются на экране извне и перемещаются к центру экрана.
- Конечный переход определяет порядок исчезновения с экрана представлений в операции. Например, в конечном переходе explodeпредставления исчезают с экрана в направлении из центра к краям.
- Переход общих элементов определяет порядок перехода между операциями представлений, используемых в обеих операциях. Например, если в двух операциях используется одно и то же изображение, но в разных позициях и с разными размерами, в случае применения перехода общего элемента changeImageTransform выполняется плавное перемещение и масштабирование изображения между этими операциями.
В Android 5.0 (уровень API 21) поддерживаются следующие начальные и конечные переходы:
- explode — перемещение представлений в центр экрана или из центра;
- slide — перемещение представлений к одному из краев экрана или от него;
- fade — отображение или скрытие представления на экране путем изменения его прозрачности.
Любой переход, являющийся наследованием класса Visibility
, поддерживается как начальный или конечный переход. Дополнительные сведения представлены в справке по API для класса Transition
.
В Android 5.0 (уровень API 21) также поддерживаются следующие переходы общих элементов:
- changeBounds — анимация изменений границ макетов целевых представлений;
- changeClipBounds — анимация изменений границ обрезки целевых представлений;
- changeTransform — анимация изменений параметров масштабирования и поворота целевых представлений;
- changeImageTransform — анимация изменений размеров и параметров масштабирования целевых изображений.
Если активировать переходы в приложении, то между начальной и конечной операциями активируется стандартный переход методом плавной замены.
Определение настраиваемых переходов
Сначала необходимо активировать переходы содержимого окна с помощью атрибутаandroid:windowContentTransitions
при определении стиля, наследуемого из темы Material Design. В определении стиля можно указать начальный и конечный переходы, а также переходы общих элементов:
<style name="BaseAppTheme" parent="android:Theme.Material"> <!-- enable window content transitions --> <item name="android:windowContentTransitions">true</item> <!-- specify enter and exit transitions --> <item name="android:windowEnterTransition">@transition/explode</item> <item name="android:windowExitTransition">@transition/explode</item> <!-- specify shared element transitions --> <item name="android:windowSharedElementEnterTransition"> @transition/change_image_transform</item> <item name="android:windowSharedElementExitTransition"> @transition/change_image_transform</item> </style>
Переход change_image_transform
в этом примере задается следующим образом:
<!-- res/transition/change_image_transform.xml --> <!-- (see also Shared Transitions below) --> <transitionSet xmlns:android="http://schemas.android.com/apk/res/android"> <changeImageTransform/> </transitionSet>
Элемент changeImageTransform
соответствует классу ChangeImageTransform
. Дополнительные сведения представлены в справке по API для Transition
.
Чтобы активировать в своем коде переходы содержимого окна, вызовите методWindow.requestFeature()
:
// inside your activity (if you did not enable transitions in your theme) getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); // set an exit transition getWindow().setExitTransition(new Explode());
Чтобы задать переходы в своем коде, вызовите следующие методы с использованием объектаTransition
:
Window.setEnterTransition()
;Window.setExitTransition()
;Window.setSharedElementEnterTransition()
;Window.setSharedElementExitTransition()
.
Методы setExitTransition()
и setSharedElementExitTransition()
задают конечный переход для вызывающей операции. Методы setEnterTransition()
и setSharedElementEnterTransition()
задают начальный переход для вызываемой операции.
Чтобы в полной мере реализовать возможности перехода, необходимо активировать переходы содержимого окна как в вызывающей, так и в вызываемой операции. В противном случае вызывающая операция запустит конечный переход, однако будет выполнен переход окна (например, масштабирование или затемнение).
Чтобы запустить начальный переход как можно раньше, используйте в вызываемой операции методWindow.setAllowEnterTransitionOverlap()
. Это позволит сделать начальные переходы более эффектными.
Запуск операции с помощью переходов
Если в приложении разрешены переходы и для операции задан конечный переход, переход активируется при запуске другой операции следующим образом:
startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
Если для второй операции задан начальный переход, он также активируется при запуске операции. Чтобы отключить переходы при запуске другой операции, укажите значение null
для набора параметров.
Запуск операции с помощью общего элемента
Порядок анимации перехода на экране между двумя операциями с общим элементом
- Активируйте в своей теме переходы содержимого окна.
- В определении стиля укажите переходы общих элементов.
- Определите свой переход как XML-ресурс.
- Присвойте одинаковое имя общим элементам в обоих макетах, используя для этого атрибут
android:transitionName
. - Воспользуйтесь методом
ActivityOptions.makeSceneTransitionAnimation()
.
// get the element that receives the click event final View imgContainerView = findViewById(R.id.img_container); // get the common element for the transition in this activity final View androidRobotView = findViewById(R.id.image_small); // define a click listener imgContainerView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(this, Activity2.class); // create the transition animation - the images in the layouts // of both activities are defined with android:transitionName="robot" ActivityOptions options = ActivityOptions .makeSceneTransitionAnimation(this, androidRobotView, "robot"); // start the new activity startActivity(intent, options.toBundle()); } });
Для общих динамических представлений, создаваемых в коде, используйте методView.setTransitionName()
для определения одинакового имени элемента в обеих операциях.
Чтобы выполнить анимацию обратного перехода по завершении второй операции, вызовите методActivity.finishAfterTransition()
вместоActivity.finish()
.
Запуск операции с несколькими общими элементами
Чтобы создать анимацию перехода на экране между двумя операциями с несколькими общими элементами, определите общие элементы в обоих макетах с помощью атрибутаandroid:transitionName
(или воспользуйтесь методом View.setTransitionName()
в обеих операциях), а затем создайте объект ActivityOptions
, как указано ниже.
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this, Pair.create(view1, "agreedName1"), Pair.create(view2, "agreedName2"));
Использование перемещения по кривой
При анимации в Material Design используются кривые для интерполяции по времени и создания схем перемещения в пространстве. В Android 5.0 (уровень API 21) и более поздних версиях имеется возможность определить для анимаций настраиваемые кривые синхронизации и схемы перемещения по кривой.
Класс PathInterpolator
— это новый интерполятор на основе кривой Безье или объекта Path
. Данный интерполятор определяет перемещение по кривой в квадрате 1 x 1 с привязкой в точках (0,0) и (1,1), а также с контрольными точками, задаваемыми с помощью аргументов конструктора. Также можно определить интерполятор траектории в качестве XML-ресурса:
<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android" android:controlX1="0.4" android:controlY1="0" android:controlX2="1" android:controlY2="1"/>
В системе имеются XML-ресурсы для трех основных кривых в спецификации Material Design:
@interpolator/fast_out_linear_in.xml
;@interpolator/fast_out_slow_in.xml
;@interpolator/linear_out_slow_in.xml
.
Можно передать объект PathInterpolator
в метод Animator.setInterpolator()
.
Класс ObjectAnimator
имеет новые конструкторы, с помощью которых можно анимировать координаты вдоль траектории перемещения, используя для этого не менее двух свойств. Например, следующий аниматор использует объект Path
для анимации свойств представления по осям X и Y:
ObjectAnimator mAnimator; mAnimator = ObjectAnimator.ofFloat(view, View.X, View.Y, path); ... mAnimator.start();
Анимация изменений состояния представления
С помощью класса StateListAnimator
можно определить аниматоры, которые запускаются при изменении состояния представления. В следующем примере показан порядок определенияStateListAnimator
в качестве XML-ресурса:
<!-- animate the translationZ property of a view when pressed --> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true"> <set> <objectAnimator android:propertyName="translationZ" android:duration="@android:integer/config_shortAnimTime" android:valueTo="2dp" android:valueType="floatType"/> <!-- you could have other objectAnimator elements here for "x" and "y", or other properties --> </set> </item> <item android:state_enabled="true" android:state_pressed="false" android:state_focused="true"> <set> <objectAnimator android:propertyName="translationZ" android:duration="100" android:valueTo="0" android:valueType="floatType"/> </set> </item> </selector>
Чтобы присоединить к представлению настраиваемые анимации состояния представления, определите аниматор, используя элемент selector
в файле XML-ресурса (как в этом примере), а затем назначьте его своему представлению с помощью атрибута android:stateListAnimator
. Чтобы в своем коде назначить представлению аниматор списка состояний, используйте методAnimationInflater.loadStateListAnimator()
, а затем назначьте аниматор своему представлению с помощью метода View.setStateListAnimator()
.
Если ваша тема является расширением темы Material Design, по умолчанию у кнопок имеется возможность анимации по оси Z. Чтобы отключить такое поведение кнопок, задайте для атрибутаandroid:stateListAnimator
значение @null
.
С помощью класса AnimatedStateListDrawable
можно создавать элементы, которые служат для отображения анимации между изменениями состояния связанного представления. В Android 5.0 в некоторых системных виджетах такая анимация используется по умолчанию. В следующем примере показан порядок определения AnimatedStateListDrawable
в качестве XML-ресурса:
<!-- res/drawable/myanimstatedrawable.xml --> <animated-selector xmlns:android="http://schemas.android.com/apk/res/android"> <!-- provide a different drawable for each state--> <item android:id="@+id/pressed" android:drawable="@drawable/drawableP" android:state_pressed="true"/> <item android:id="@+id/focused" android:drawable="@drawable/drawableF" android:state_focused="true"/> <item android:id="@id/default" android:drawable="@drawable/drawableD"/> <!-- specify a transition --> <transition android:fromId="@+id/default" android:toId="@+id/pressed"> <animation-list> <item android:duration="15" android:drawable="@drawable/dt1"/> <item android:duration="15" android:drawable="@drawable/dt2"/> ... </animation-list> </transition> ... </animated-selector>
Анимация векторных элементов
Векторные элементы можно масштабировать без ущерба четкости. Класс AnimatedVectorDrawable
позволяет анимировать свойства векторного элемента.
Анимированные векторные элементы обычно определяются в трех XML-файлах:
- векторный элемент с элементом
<vector>
вres/drawable/
; - анимированный векторный элемент с элементом
<animated-vector>
вres/drawable/
; - один или несколько аниматоров для объектов с элементом
<objectAnimator>
вres/anim/
.
С помощью анимированных векторных элементов можно анимировать атрибуты элементов <group>
и<path>
. Элемент<group>
определяет набор траекторий или подгрупп, а элемент <path>
— траектории для прорисовки.
При определении векторного элемента, который требуется анимировать, используйте атрибутandroid:name
для назначения уникальных имен группам или траекториям, чтобы на них можно было сослаться в определениях аниматора. Например:
<!-- res/drawable/vectordrawable.xml --> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="64dp" android:width="64dp" android:viewportHeight="600" android:viewportWidth="600"> <group android:name="rotationGroup" android:pivotX="300.0" android:pivotY="300.0" android:rotation="45.0" > <path android:name="v" android:fillColor="#000000" android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" /> </group> </vector>
Определение анимированного векторного элемента ссылается на группы и траектории в векторном элементе, используя их имена:
<!-- res/drawable/animvectordrawable.xml --> <animated-vector xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/vectordrawable" > <target android:name="rotationGroup" android:animation="@anim/rotation" /> <target android:name="v" android:animation="@anim/path_morph" /> </animated-vector>
Определения анимации представляются объектами ObjectAnimator
или AnimatorSet
. Первый аниматор в этом примере поворачивает целевую группу на 360 градусов:
<!-- res/anim/rotation.xml --> <objectAnimator android:duration="6000" android:propertyName="rotation" android:valueFrom="0" android:valueTo="360" />
Второй аниматор в этом примере преобразует траекторию векторного элемента из одной формы в другую. Для преобразования обе траектории должны быть совместимы: они должны содержать одинаковое количество команд, а также одинаковое количество параметров для каждой команды.
<!-- res/anim/path_morph.xml --> <set xmlns:android="http://schemas.android.com/apk/res/android"> <objectAnimator android:duration="3000" android:propertyName="pathData" android:valueFrom="M300,70 l 0,-70 70,70 0,0 -70,70z" android:valueTo="M300,70 l 0,-70 70,0 0,140 -70,0 z" android:valueType="pathType" /> </set>
Дополнительные сведения представлены в справке по API для AnimatedVectorDrawable
.