Android动画深入分析
View动画
View动画的种类
View动画的四种变化:平移动画,缩放动画,旋转动画和透明度动画。这四种变化对应着Animation的四个子类分别是TranslateAnimation,ScaleAnimation,RotateAnimation和AlphaAnimation。对于View动画来说,建议采用XML来定义,可读性更好
要使用View动画,首先要创建动画的XML文件,这个文件的路径为:res/anim/filename.xml。View动画是有固定语法的:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"//插值器,影响动画的速度,这个是默认值
android:shareInterpolator="true"//表示集合中动画是否和集合共用一个插值器
>
<alpha
android:fromAlpha="1.0"//表示透明度起始值
android:toAlpha="1.0"//表示透明度结束值
/>
<scale
android:fromXScale="0.0"//水平方向缩放起始值
android:toXScale="1.0"//水平方向缩放结束值
android:fromYScale="0.0"//竖直方向缩放起始值
android:toYScale="1.0"//竖直方向缩放结束值
android:pivotX="float"//缩放的轴点X坐标会影响缩放效果
android:pivotY="float"/>//缩放的轴点Y坐标会影响缩放效果
//轴点默认为中心点
<translate
android:fromYDelta="0.0"//Y起始值
android:fromXDelta="0.0"//X起始值
android:toXDelta="1.0"//X结束值
android:toYDelta="1.0"/>//Y结束值
<rotate
android:fromDegrees="0"//旋转开始的角度
android:toDegrees="180"//旋转结束的角度
android:pivotY="float"//旋转轴点的x坐标
android:pivotX="float"/>//旋转轴点的y坐标
</set>
android:duration//动画持续时间
android:fillAfter//动画结束以后View是否留在结束位置,true停留false不停
如何应用动画
1
2
3Button button=(Button) findViewById(R.id.button1);
Animation animation=AnimationUtils.loadAnimation(this,R.anim.animation_test);
button.startAnimation(animation);
帧动画
帧动画是顺序播放一组预先定义好的图片类似于电影播放。使用AnimationDrawable来使用帧动画。
用法:
先定义一个AnimationDrawable
1
2
3
4
5
6
7
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/avatar1" android:duration="500"/>
<item android:drawable="@drawable/avatar2" android:duration="500"/>
<item android:drawable="@drawable/avatar3" android:duration="500"/>
</animation-list>调用
1
2
3binding.button1.setBackgroundResource(R.drawable.frame_animation);
AnimationdDrawable drawable=(AnimationdDrawable) binding.button1.getBackground();
drawable.start();尽量避免使用过多尺寸较大的图片不然容易引起OOM
View动画的特殊使用场景
LayoutAnimation
这个作用于ViewGroup,为其指定一个动画,这样当他的子元素出厂时都会具备这种效果,这种效果常常被用在ListView上面
实现步骤
定义LayoutAnimation
1
2
3
4
5
6
7
8//res/anim/anim_layout.xml
<layoutAnimation
xmlns:android="http://schemas.android.com/apk/res/android"
android:delay="0.5"
android:animationOrder="normal"
android:animation="@anim/anim_item" />为子元素指定出场动画
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="300"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:shareInterpolator="true"
>
<alpha
android:fromAlpha="1.0"
android:toAlpha="1.0"
/>
<scale
android:fromXScale="0.0"
android:toXScale="1.0"
android:fromYScale="0.0"
android:toYScale="1.0"
android:pivotX="float"
android:pivotY="float"/>
<translate
android:fromYDelta="0.0"
android:fromXDelta="0.0"
android:toXDelta="1.0"
android:toYDelta="1.0"/>
<rotate
android:fromDegrees="0"
android:toDegrees="180"
android:pivotY="float"
android:pivotX="float"/>
</set>为ViewGroup指定android:layoutAnimation属性
1
2
3
4
5
6
7
8
9
10<ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layoutAnimation="@anim/anim_layout"
......
......
......
/>
Activity的切换方式
Activity有默认的切换效果,但是这个效果我们可以自定义,主要用到overridePendingTransition(int enterAnim,int exitAnim)这个方法,这个方法必须在startActivity或者finish之后调用才可以生效它的参数含义:
- enterAnim,Activity被打开时所需要的动画资源id
- exitAnim,Activity被暂停时所需要的动画资源id
实现:
启动
1
2
3Intent intent=new Intent(this,TestActivity.class);
startActivity(intent);
overridePendingTransition(R.anim.enter_anim,R.anim.exit_anim);退出
1
2
3
4
5
public void finish(){
super.finish();
overridePendingTransition(R.anim.enter_anim,R.anim.exit_anim);
}
使用属性动画
ValueAnimator
1
2
3
4
5
6ValueAnimator colorAnim = ObjectAnimator.ofInt(this, "backgroundColor", /*Red*/0xFFFF8080, /*Blue*/0xFF8080FF);
colorAnim.setDuration(3000);
colorAnim.setEvaluator(new ArgbEvaluator());
colorAnim.setRepeatCount(ValueAnimator.INFINITE); // 无限循环
colorAnim.setRepeatMode(ValueAnimator.REVERSE); // 反转效果
colorAnim.start();ObjectAnimator
1
ObjectAnimator.ofFloat(myObject, "translationY", -myObject.getHeight()).start();//负数代表向上移动
AnimatorSet
1
2
3
4
5
6
7
8
9
10
11
12AnimatorSet set = new AnimatorSet();
set.playTogether(
ObjectAnimator.ofFloat(myView, "rotationX", 0, 360),
ObjectAnimator.ofFloat(myView, "rotationY", 0, 180),
ObjectAnimator.ofFloat(myView, "rotation", 0, -90),
ObjectAnimator.ofFloat(myView, "translationX", 0, 90),
ObjectAnimator.ofFloat(myView, "translationY", 0, 90),
ObjectAnimator.ofFloat(myView, "scaleX", 1, 1.5f),
ObjectAnimator.ofFloat(myView, "scaleY", 1, 0.5f),
ObjectAnimator.ofFloat(myView, "alpha", 1, 0.25f, 1)
);
set.setDuration(5 * 1000).start();
使用动画的注意事项
OOM 问题
主要发生在帧动画里,图片数量多且图片较大时就容易出现这种情况,在实际开发中应尽量避免使用复杂的帧动画。
内存泄漏
属性动画中的无限循环动画。这类动画需要在Activity退出时及时停止不然会造成内存泄漏。必须在
onPause()或onDestroy()中调用anim.cancel()停止动画。兼容性问题
动画在 Android 3.0 (API 11) 以下的系统上可能存在无法正常工作的情况,需做好适配。
View动画的问题
View 动画只是影像的改变,不是真正改变 View 的状态。有时候动画完成后,调用
setVisibility(View.GONE)可能失效。这个时候只要调用view.clearAnimation()清除View动画即可解决不要使用px
动画中尽量不要使用px,尽量用dp
动画元素的交互
这是 View 动画 与 属性动画 的本质区别:
- View 动画: 移动后,点击事件仍在原位。视觉在 A 点,点击响应还在起始点。
- 属性动画: 从 Android 3.0 开始,属性动画移动后,点击事件随之移动。视觉在 B 点,点击响应也在 B 点。
硬件加速
建议使用动画时开启硬件加速,这能显著提高动画的流畅度,减少卡顿。




