Android三种动画:
1. 帧动画
按顺序播放一组预定义的图片
- 在res/drawable目录下定义一个XML文件,根节点为系统提供的animation-list,然后放入定义好的图片
- 使用AnimationDrawable类播放定义好的drawable图片
2. 补间动画(View动画)
View动画是Android一开始就提供的比较原始的动画,主要支持四种效果:
- 平移(TranslateAnimation -
) - 缩放(ScaleAnimation -
) - 旋转(RotateAnimation -
) - 透明度(AlphaAnimation -
)
可以通过在res/anim下创建xml动画文件或者代码实现:
1 | <?xml version="1.0" encoding="utf-8"?> |
自定义View动画
- 重写initialize和applyTransformation,很多时候采用Camera简化矩阵变化,
自定义View动画的过程主要是矩阵变换的过程。
补间动画的使用场景:
LayoutAnimation,给ViewGroup指定child的出场动画,常常用在ListView等列表控件上
定义LayoutAnimation:delay,animationOrder,animation等属性
子元素的具体动画效果
为ViewGroup指定android:layoutAnimation属性或者通过LayoutAnimationController实现。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
android:animation="@anim/test_anim"
android:delay="0.5"
android:animationOrder="normal">
</layoutAnimation>
// xml指定
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layoutAnimation="@anim/layout_anim" />
// 代码指定
Animation animation1 = AnimationUtils.loadAnimation(this, R.anim.layout_anim);
LayoutAnimationController controller = new LayoutAnimationController(animation1);
controller.setDelay(0.5f);
controller.setOrder(LayoutAnimationController.ORDER_NORMAL);
listView.setLayoutAnimation(controller);
Activity/Fragment的切换效果
- activity overridePendingTransition,在startActivity和finish之后调用
- FragmentTransaction.setCustomAnimations
补间动画的原理
补间动画的核心本质就是在一定的持续时间内,不断改变 Matrix 变换,并且不断刷新的过程。
虽然 View 做了属性上的改变,但其实并没有更改 View 的 left、right、top、bottom 这些属性
3. 属性动画
- ObjectAnimator
- ValueAnimator
- AnimationSet
1 | ObjectAnimator.ofFloat(view, "translationX", 0).start(); |
- 监听器
1 | AnimatorListener: |
属性动画的监听器
AnimatorUpdateListener:
1
2
3
4// 监听整个动画过程,动画每播放一帧,onAnimationUpdate会被调用一次
public static interface AnimatorUpdateListener {
void onAnimationUpdate(ValueAnimator animation);
}AnimatorListener:
1
2
3
4
5
6
7
8// 监听动画开始结束取消及重复播放
// 系统还提供了AnimatorListenerAdapter,方便使用
public static interface AnimatorListener{
void onAnimationStart(Animator animation);
void onAnimationEnd(Animator animation);
void onAnimationCancel(Animator animation);
void onAnimationRepeat(Animator animation);
}
对任意属性做动画
对Object的属性abc做动画,需要满足的条件:
- Object提供setAbc方法,如果动画没有传入初始值,那么还要提供getAbc方法,因为系统会去取abc的初始值
- Object的setAbc对属性abc所做的改变有UI体现,不然没有视觉效果
不满足的解决方案:
- 有权限的话添加set/get方法
- 借助包装类,间接提供set/get方法
- 采用ValueAnimator,监听动画过程,自己实现属性的改变
属性动画的原理
在一定的时间间隔内,通过不断地对值进行改变,并不断将该值赋给对象的属性,从而实现该对象在属性上的动画效果。
ViewGroup 在 getTransformedMotionEvent() 方法中会通过子 View 的 hasIdentityMatrix() 方法来判断子 View 是否应用过位移、缩放、旋转之类的属性动画。如果应用过的话,那还会调用子 View 的 getInverseMatrix() 做「反平移」操作,然后再去判断处理后的触摸点是否在子 View 的边界范围内。
插值器和估值器
- 插值器:设置的属性值从初始值过渡到结果值的变化规律,应用场景: 实现非线性运动的动画效果
- 估值器:设置 属性值 从初始值过渡到结束值 的变化具体数值, 插值器(Interpolator)决定 值 的变化规律(匀速、加速blabla),即决定的是变化趋势;而接下来的具体变化数值则交给
而估值器, 属性动画特有的属性,应用场景: 协助插值器 实现非线性运动的动画效果
动画默认刷新频率 10ms/帧
常见问题?
- 使用动画的注意事项有哪些?
- OOM,主要出现在帧动画中
- 内存泄漏:属性动画中无限循环的动画在Activity退出时要及时停止。
- 兼容性问题
- View动画问题:View动画是对View的影像做动画,并未真正改变View状态,例如会出现动画结束后setVisibility(View.GONE)失效,需要调用view.clearAnimation
- 不要使用px,可能会存在设备适配问题
- 动画元素的交互:属性动画可以,ViewGroup 在 getTransformedMotionEvent() 方法中会通过子 View 的 hasIdentityMatrix() 方法来判断子 View 是否应用过位移、缩放、旋转之类的属性动画。如果应用过的话,那还会调用子 View 的 getInverseMatrix() 做「反平移」操作,然后再去判断处理后的触摸点是否在子 View 的边界范围内。
- 硬件加速