继上一篇Android的LayoutAnimation,在Android中给单个View设置动画所用到的动画是视图动画(补间动画)和帧动画(DrawableAnimation)
ViewAnimation
是Android 中最简单的动画,可以分为AlphaAnimation
,RotateAnimation
,ScaleAnimation
,TranslateAnimation
和AnimationSet
,其中动画监听器为AnimationListener
他们都可以在代码和xml中设置生效,
"1.0" encoding="utf-8"?>
"http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromXDelta="-100%"
android:fromYDelta="0"
android:toXDelta="100%p"
android:toYDelta="0"/>
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属性及用法
android:repeatMode 设置动画重复执行的模式,可设为以下两个值其中之一:
- restart 动画重复执行时从起点开始,默认为该值
- reverse 动画会反方向执行
android:startOffset 设置动画执行之前的等待时长,毫秒为单位;重复执行时,每次执行前同样也会等待一段时间
android:zAdjustment 表示被设置动画的内容在动画运行时在Z轴上的位置,取值为以下三个值之一:
- normal 默认值,保持内容在Z轴上的位置不变
- top 保持在Z周最上层
- bottom 保持在Z轴最下层
android:interpolator 设置动画速率的变化,比如加速、减速、匀速等,需要指定Interpolator资源,后面再详细讲解
标签还有个android:shareInterpolator属性,设置为true时则可将interpolator应用到所有子元素中
自定义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
上,而且在动画结束后其事件响应还在源位置
Drawable Animation 可以让我们按顺序加载一系列的资源来创建一个动画。就像电影一帧帧的播放那样.最终会生成一个Drawable.接下来我们看一下两种可以实现动画的Drawable.
这种方式有一个缺点,就是会有很多的资源文件,使用不当,会导致内存溢出
<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();
}
}
在Android中还有一种是为Rotate而设置的Drawable动画,使用的标签是
animated-rotate
,会生成AnimatedRotateDrawable
,但是AnimatedRotateDrawable
是一个被@hide
的类,使用如下
<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