page.title=Определение настраиваемой анимации @jd:body
Благодаря анимациям в Material Design пользователи получают отклик на выполняемые действия. Кроме того, анимации обеспечивают зрительную связь при взаимодействии с приложением. Тема Material Design содержит ряд анимаций по умолчанию для кнопок и переходов, а в Android 5.0 (уровень API 21) и более поздних версиях можно настраивать эти анимации и создавать новые:
Реакция на касание в Material Design обеспечивает моментальное визуальное подтверждение взаимодействия пользователя с элементами интерфейса в точке касания. В стандартной анимации для реакции на нажатие кнопок используется новый класс {@link android.graphics.drawable.RippleDrawable}, обеспечивающий переход между разными состояниями с созданием эффекта ряби.
В большинстве случаев эту возможность следует применять в XML-файле представления, указав фон представления следующим образом:
?android:attr/selectableItemBackground для ограниченной области ряби;?android:attr/selectableItemBackgroundBorderless для ряби, распространяемой за границы представления.
При отрисовке она будет ограничиваться ближайшим родительским элементом представления со значением фона, отличным от null.
Примечание. selectableItemBackgroundBorderless — это новый атрибут, представленный в уровне API 21.
Также можно определить {@link android.graphics.drawable.RippleDrawable}
в качестве XML-ресурса с помощью элемента ripple.
Можно назначить цвет для объектов {@link android.graphics.drawable.RippleDrawable}. Чтобы
изменить стандартный цвет отклика на касание, воспользуйтесь атрибутом темы android:colorControlHighlight
.
Дополнительные сведения представлены в справке по API для класса {@link android.graphics.drawable.RippleDrawable}.
Анимация эффекта появления обеспечивает зрительную связь с действиями пользователя, когда отображается или скрывается группа элементов интерфейса. С помощью метода {@link android.view.ViewAnimationUtils#createCircularReveal 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();
Рисунок 1. Переход с общими элементами.
Для воспроизведения фильма нажмите экран устройстваПереходы в приложениях Material Design обеспечивают зрительные связи между различными состояниями путем движения элементов и преобразований между общими элементами. Можно выбрать настраиваемые анимации для начальных и конечных переходов, а также для переходов общих элементов между операциями.
В Android 5.0 (уровень API 21) поддерживаются следующие начальные и конечные переходы:
Любой переход, являющийся наследованием класса {@link android.transition.Visibility}, поддерживается как начальный или конечный переход. Дополнительные сведения представлены в справке по API для класса {@link android.transition.Transition}.
В Android 5.0 (уровень API 21) также поддерживаются следующие переходы общих элементов:
Если активировать переходы в приложении, то между начальной и конечной операциями активируется стандартный переход методом плавной замены.
Рисунок 2. Переход с одним общим элементом.
Сначала необходимо активировать переходы содержимого окна с помощью атрибута 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 соответствует классу
{@link android.transition.ChangeImageTransform}. Дополнительные сведения представлены в справке по API для {@link android.transition.Transition}.
Чтобы активировать в своем коде переходы содержимого окна, вызовите метод {@link android.view.Window#requestFeature 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());
Чтобы задать переходы в своем коде, вызовите следующие методы с использованием объекта {@link android.transition.Transition}:
Методы {@link android.view.Window#setExitTransition setExitTransition()} и {@link android.view.Window#setSharedElementExitTransition setSharedElementExitTransition()} задают конечный переход для вызывающей операции. Методы {@link android.view.Window#setEnterTransition setEnterTransition()} и {@link android.view.Window#setSharedElementEnterTransition setSharedElementEnterTransition()} задают начальный переход для вызываемой операции.
Чтобы в полной мере реализовать возможности перехода, необходимо активировать переходы содержимого окна как в вызывающей, так и в вызываемой операции. В противном случае вызывающая операция запустит конечный переход, однако будет выполнен переход окна (например, масштабирование или затемнение).
Чтобы запустить начальный переход как можно раньше, используйте в вызываемой операции метод {@link android.view.Window#setAllowEnterTransitionOverlap Window.setAllowEnterTransitionOverlap()} . Это позволит сделать начальные переходы более эффектными.
Если в приложении разрешены переходы и для операции задан конечный переход, переход активируется при запуске другой операции следующим образом:
startActivity(intent,
ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
Если для второй операции задан начальный переход, он также активируется при запуске операции.
Чтобы отключить переходы при запуске другой операции, укажите
значение null для набора параметров.
Порядок анимации перехода на экране между двумя операциями с общим элементом
android:transitionName.
// 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());
}
});
Для общих динамических представлений, создаваемых в коде, используйте метод {@link android.view.View#setTransitionName View.setTransitionName()} для определения одинакового имени элемента в обеих операциях.
Чтобы выполнить анимацию обратного перехода по завершении второй операции, вызовите метод {@link android.app.Activity#finishAfterTransition Activity.finishAfterTransition()} вместо{@link android.app.Activity#finish Activity.finish()}.
Чтобы создать анимацию перехода на экране между двумя операциями с несколькими общими
элементами, определите общие элементы в обоих макетах с помощью атрибута android:transitionName
(или воспользуйтесь методом {@link android.view.View#setTransitionName View.setTransitionName()} в обеих
операциях), а затем создайте объект {@link android.app.ActivityOptions}, как указано ниже.
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(this,
Pair.create(view1, "agreedName1"),
Pair.create(view2, "agreedName2"));
При анимации в Material Design используются кривые для интерполяции по времени и создания схем перемещения в пространстве. В Android 5.0 (уровень API 21) и более поздних версиях имеется возможность определить для анимаций настраиваемые кривые синхронизации и схемы перемещения по кривой.
Класс {@link android.view.animation.PathInterpolator} — это новый интерполятор на основе кривой Безье или объекта {@link android.graphics.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.Можно передать объект {@link android.view.animation.PathInterpolator} в метод {@link android.animation.Animator#setInterpolator Animator.setInterpolator()}.
Класс {@link android.animation.ObjectAnimator} имеет новые конструкторы, с помощью которых можно анимировать координаты вдоль траектории перемещения, используя для этого не менее двух свойств. Например, следующий аниматор использует объект {@link android.graphics.Path} для анимации свойств представления по осям X и Y:
ObjectAnimator mAnimator; mAnimator = ObjectAnimator.ofFloat(view, View.X, View.Y, path); ... mAnimator.start();
С помощью класса {@link android.animation.StateListAnimator} можно определить аниматоры, которые запускаются при изменении состояния представления. В следующем примере показан порядок определения {@link android.animation.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. Чтобы в своем коде назначить представлению аниматор
списка состояний, используйте метод {@link android.animation.AnimatorInflater#loadStateListAnimator
AnimationInflater.loadStateListAnimator()}, а затем назначьте аниматор своему представлению с помощью метода
{@link android.view.View#setStateListAnimator View.setStateListAnimator()}.
Если ваша тема является расширением темы Material Design, по умолчанию у кнопок имеется возможность анимации по оси Z. Чтобы отключить
такое поведение кнопок, задайте для атрибута android:stateListAnimator значение
@null.
С помощью класса {@link android.graphics.drawable.AnimatedStateListDrawable} можно создавать элементы, которые служат для отображения анимации между изменениями состояния связанного представления. В Android 5.0 в некоторых системных виджетах такая анимация используется по умолчанию. В следующем примере показан порядок определения {@link android.graphics.drawable.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>
Векторные элементы можно масштабировать без ущерба четкости. Класс {@link android.graphics.drawable.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>
Определения анимации представляются объектами {@link android.animation.ObjectAnimator} или {@link android.animation.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 для {@link android.graphics.drawable.AnimatedVectorDrawable}.