概述
继上一篇Android的LayoutAnimation,在Android中给单个View设置动画所用到的动画是视图动画(补间动画)和帧动画(DrawableAnimation)
ViewAnimation
ViewAnimation
是Android 中最简单的动画,可以分为AlphaAnimation
,RotateAnimation
,ScaleAnimation
,TranslateAnimation
和AnimationSet
,其中动画监听器为AnimationListener
他们都可以在代码和xml中设置生效,
- xml生成动画,需要放在anim目录下
<!--res/anim/left_to_right.xml-->
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromXDelta="-100%"
android:fromYDelta="0"
android:toXDelta="100%p"
android:toYDelta="0"/>
<!--
android:duration 动画从开始到结束持续的时长,单位为毫秒
android:fromXDelta 起始位置的X坐标的偏移量
android:toXDelta 结束位置的X坐标的偏移量
android:fromYDelta 起始位置的Y坐标的偏移量
android:toYDelta 结束位置的Y坐标的偏移量
坐标的值可以有三种格式:从-100到100,以"%"结束,表示相对于View本身的百分比位置;
如果以"%p"结束,表示相对于View的父View的百分比位置;
如果没有任何后缀,表示相对于View本身具体的像素值。
-->
Animation animation = AnimationUtils.loadAnimation(mActivity, R.anim.move_left_to_right_translate);
animation.setAnimationListener(animationListener);
mText1.startAnimation(animation);
- 代码生成动画
private TranslateAnimation createTranslateAnimation() {
TranslateAnimation translateAnimation =
new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 100f,
Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 100f);
translateAnimation.setDuration(1000);
return translateAnimation;
}
关于属性中的 数值
%
%p
的异同,可以参考自定义控件三部曲之动画篇(一)——alpha、scale、translate、rotate、set的xml属性及用法
xml中的通用属性
- android:duration 动画从开始到结束持续的时长,单位为毫秒
- android:detachWallpaper 设置是否在壁纸上运行,只对设置了壁纸背景的窗口动画(window animation)有效。设为true,则动画只在窗口运行,壁纸背景保持不变
- android:fillAfter 设置为true时,动画执行完后,View会停留在动画的最后一帧;默认为false;如果是动画集,需在标签中设置该属性才有效
- android:fillBefore 设置为true时,动画执行完后,View回到动画执行前的状态,默认即为true
- android:fillEnabled 设置为true时,android:fillBefore的值才有效,否则android:fillBefore会被忽略
- android:repeatCount 设置动画重复执行的次数,默认为0,即不重复;可设为-1或infinite,表示无限重复
android:repeatMode 设置动画重复执行的模式,可设为以下两个值其中之一:
- restart 动画重复执行时从起点开始,默认为该值
- reverse 动画会反方向执行
android:startOffset 设置动画执行之前的等待时长,毫秒为单位;重复执行时,每次执行前同样也会等待一段时间
android:zAdjustment 表示被设置动画的内容在动画运行时在Z轴上的位置,取值为以下三个值之一:
- normal 默认值,保持内容在Z轴上的位置不变
- top 保持在Z周最上层
- bottom 保持在Z轴最下层
android:interpolator 设置动画速率的变化,比如加速、减速、匀速等,需要指定Interpolator资源,后面再详细讲解
<set>
标签还有个android:shareInterpolator属性,设置为true时则可将interpolator应用到所有子元素中
自定义ViewAnimation
自定义Animation
原理: 在ViewGroup
的drawChild
方法获取该View
的Transformation
值,然后调用canvas.concat(transformationToApply.getMatrix())
通过矩阵运算完成动画,如果动画尚未完成,继续调用invalidate
启动下次绘制,从而完成动画的绘制.如果涉及到3D变换,需要用到Camera
对象
示例
public class Custom3DAnimation extends Animation {
private int mCenterWidth;
private int mCenterHeight;
private Camera mCamera = new Camera();
private float mRotateY = 0.0f;
@Override
public void initialize(int width, int height, int parentWidth, int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
setDuration(2000);// 设置默认时长
setFillAfter(true);// 动画结束后保留状态
setInterpolator(new BounceInterpolator());// 设置默认插值器
mCenterWidth = width / 2;
mCenterHeight = height / 2;
}
// 暴露接口-设置旋转角度
public void setRotateY(float rotateY) {
mRotateY = rotateY;
}
@Override
protected void applyTransformation( float interpolatedTime, Transformation t) {
final Matrix matrix = t.getMatrix();
mCamera.save();
mCamera.rotateY(mRotateY * interpolatedTime);// 使用Camera设置旋转的角度
mCamera.getMatrix(matrix);// 将旋转变换作用到matrix上
mCamera.restore();
// 通过pre方法设置矩阵作用前的偏移量来改变旋转中心
matrix.preTranslate(mCenterWidth, mCenterHeight);
matrix.postTranslate(-mCenterWidth, -mCenterHeight);
}
}
applyTransformation方法的第一个参数interpolatedTime是插值器的时间因子,取值在0到1之间;第二个参数Transformation是矩阵的封装类,一般使用它来获得当前的矩阵Matrix对象,然后对矩阵进行操作,就可以实现动画效果了
缺点:ViewAnimation只能作用于View
上,而且在动画结束后其事件响应还在源位置
DrawableAnimation
Drawable Animation 可以让我们按顺序加载一系列的资源来创建一个动画。就像电影一帧帧的播放那样.最终会生成一个Drawable.接下来我们看一下两种可以实现动画的Drawable.
AnimationDrawable
这种方式有一个缺点,就是会有很多的资源文件,使用不当,会导致内存溢出
- 定义xml文件,需要放在drawable目录下
<!--res/drawable/progress_drawable_white.xml-->
<?xml version="1.0" encoding="utf-8"?>
<animation-list android:oneshot="false"
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:duration="83" android:drawable="@drawable/ic_loading_white1" />
<item android:duration="83" android:drawable="@drawable/ic_loading_white2" />
<item android:duration="83" android:drawable="@drawable/ic_loading_white3" />
<item android:duration="83" android:drawable="@drawable/ic_loading_white4" />
</animation-list>
在代码中会生成一个AnimationDrawable的实例
,
mIcon1.setImageResource(R.drawable.progress_drawable_white);
AnimationDrawable animationDrawable = (AnimationDrawable) mIcon2.getDrawable();
if (null != animationDrawable){
if (!animationDrawable.isRunning()) {
_v.setText("停止");
animationDrawable.start();
} else {
_v.setText("开始");
animationDrawable.stop();
}
}
AnimatedRotateDrawable
在Android中还有一种是为Rotate而设置的Drawable动画,使用的标签是
animated-rotate
,会生成AnimatedRotateDrawable
,但是AnimatedRotateDrawable
是一个被@hide
的类,使用如下
- 定义xml,放在drawable下
<?xml version="1.0" encoding="utf-8"?>
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_loading_white1"
android:pivotX="50%"
android:pivotY="50%"/>
这种方式之需要一张图片即可实现旋转动画
- 代码控制
// 因为AnimatedRotateDrawable是不可见的,但是其实现了Animatable接口,因此可以用接口来实现控制操作
Drawable drawable = mIcon1.getDrawable();
if (null != drawable) {
Animatable animatable = (Animatable) drawable;
if (!animatable.isRunning()) {
v.setText("停止");
animatable.start();
} else {
v.setText("开始");
animatable.stop();
}
}
缺点:DrawableAnimation比较消耗资源,操作不当,会导致oom
具体源码地址;AndroidAnimations
参考:Android样式的开发:View Animation篇
Android Heroes Reading Notes 3
居中显示并旋转 android Button 里的属性drawableLeft
扩展阅读
自定义控件三部曲之动画篇(一)——alpha、scale、translate、rotate、set的xml属性及用法
Android 动画,看完这些还不够
Android动画三部曲之一 View Animation & LayoutAnimation