本文介绍了Android View层级动画的使用。
原文链接:View Hierarchy Animations
概述
过渡(Transitions)API最先在Android 4.4中(现在已兼容到Android 4.0)引入提供了一种简单的方式让Activity中的View产生动画。例如,你可以执行可见性的改变,框架来解决怎样产生动画:
Transitions API通过引入的场景(scene)的概念来工作,场景反映了一个View层级(一个容器布局例如LinearLayout,RelativeLayout等等)的快照。框架解决了场景之间出现的改变和执行一个默认的动画序列集合。
配置
如果你想支持Android 4.0的设备,确保在Gradle配置中引入了design support library。
布局修改动画
简单地调用TransitionManager
:
1 | TransitionManager.beginDelayedTransition(viewRoot); |
然后修改容器布局中的任何元素:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17ImageView circle;
boolean sizeChanged;
protected void onCreate(Bundle savedInstanceState) {
circle = (ImageView) findViewById(R.id.circle_green);
viewRoot = (ViewGroup) findViewById(R.id.my_container_layout);
ViewGroup.LayoutParams params = circle.getLayoutParams();
if (sizeChanged) {
params.width = savedWidth;
} else {
savedWidth = params.width;
params.width = 200;
}
sizeChanged = !sizeChanged;
}
然后调用setLayoutParams()
触发布局下一帧的渲染。布局将会记录circle的最终状态和产生修改动画:1
circle.setLayoutParams(params);
自定义TransitionSet
TransitionManager默认使用的精心设计的过渡是AutoTransition
,过渡执行淡入淡出,如果元素有位置或大小的变化执行移动或缩放。如果你想创建自己的序列,你可以使用内置的过渡组成:
- slide (从一边进入或退出)
- changeBounds (修改大小或移动)
- fade (修改可见性)
- changeClipBounds (调整View裁剪的边界)
- changeTransform (调整缩放或旋转)
- changeImageTransform (调整图片的大小、图形和缩放类型)
- pathMotion (允许沿着路径移动)
- explode (根据中心点滑动)
- recolor (改变背景或其它颜色)
TransitionSet可以通过代码创建或XML填充。如果你使用XML创建,放到res/transition
文件夹中。
slide_and_changebounds.xml:
1 | <transitionSet xmlns:android="http://schemas.android.com/apk/res/android" |
然后填充这个过渡:1
TransitionSet transitionSet = TransitionInflater.from(this).inflateTransition(R.transition.slide_from_bottom);
我们也可以使用Java代码创建同样的效果:1
2
3
4
5
6
7
8TransitionSet transitionSet = new TransitionSet();
Slide slide = new Slide();
slide.setInterpolator(new DecelerateInterpolator(1.5f));
ChangeBounds changeBounds = new ChangeBounds();
changeBounds.setInterpolator(new BounceInterpolator());
transitionSet.addTransition(slide);
transition.addTransition(changeBounds);
然后,我们需要创建当前布局的快照。需要修改的元素的ID应该保持一致:
1 | ViewGroup sceneRoot = (ViewGroup) findViewById(R.id.scene_root); |
在一些事件类型上,我们可以使用TransitionManager切换到下一个场景:1
TransitionManager.go(scene2, transitionSet);
你也可以使用其它方式创建场景,例如传递一个view到被填充的容器中:1
Scene scene2 = Scene(sceneRoot, view);
如果你需要执行一些额外的修改动画,你也可以使用setEnterAction()
和 setExitAction()
。
查看示例工程获取更多细节。
参考
http://code.tutsplus.com/tutorials/an-introduction-to-android-transitions--cms-21640>
https://medium.com/@andkulikov/animate-all-the-things-transitions-in-android-914af5477d50#.c93tot4td
https://www.bignerdranch.com/blog/building-animations-android-transition-framework-part-1/
https://www.bignerdranch.com/blog/building-animations-android-transition-framework-part-2/
https://developer.android.com/training/transitions/index.html
https://possiblemobile.com/2013/11/new-transitions-framework/
https://teamtreehouse.com/library/animations-and-transitions
https://medium.com/google-developers/transitions-in-the-android-support-library-8bc86a1d688e#.pbt4iu9oz
DevBytes: Android 4.4 Transitions
Google I/O 2016 talk