一直以来就想写篇关于android动画的博客,正好趁着这次的项目重新把动画整理了一篇,在以前的基础上重新梳理了一篇,颇有心得,现在写下来一起与大家分享一下。
android动画主要分为三种:补间动画,帧动画和属性动画。现在就一个一个讲解一下。
补间动画:
补间动画很简单,就是对作用的对象进行透明度(alpha),缩放(scale),位移(translate)以及旋转(rotate)的处理。注意,作用的视图仅仅只是在内容的位置发生了一些变化,其真正的位置并没有任何的改变。换句话说,就是该视图的点击位置还是在原来的地方。
补间动画有四个关键的词,上面已经说过了,很多人也许会说,这四个词谁都知道呀,但是在实际的项目开发过程中,应该如何去使用呢,下面我就把我总结出来的与大家分享下。
1> alpha(透明度)
fromAlpha:动画起始时透明度
toAlpha:动画结束时透明度
说明:
(1)取值在0.0-1.0之间的float数据类型的数字
(2)0.0表示完全透明
(3)1.0表示完全不透明
2> scale(缩放)
fromXScale:动画起始时X坐标上的伸缩尺寸
fromYScale:动画起始时Y坐标上的伸缩尺寸
toXScale: 动画结束时X坐标上的伸缩尺寸
toYScale: 动画结束时Y坐标上的伸缩尺寸
pivotX: 动画相对于物件的X坐标的开始位置
pivotY: 动画相对于物件的Y坐标的开始位置
说明:0.0表示收缩到没有
1.0表示正常无伸缩
值小于1.0表示收缩
值大于1.0表示放大
pivotX 属性为动画相对于物件的X坐标的开始位置
pivotY 属性为动画相对于物件的Y坐标的开始位置
以上两个属性值 从0%-100%中取值
50%为物件的X或Y方向坐标上的中点位置
3> translate(平移)
fromXDelta 动画起始时的X坐标的位置
fromYDelta 动画起始时的Y坐标的位置
toXDelta 动画结束时的X坐标的位置
toYDelta 动画结束时的Y坐标的位置
注意:0代表当前位置,正数向右下角移动,负数向左上角
4> rotate(旋转)
fromDegrees 动画开始的角度
toDegrees 动画结束的角度
pivotX 动画相对于物件的X坐标的开始位置
pivotY 动画相对于物件的Y坐标的开始位置
注意:一般情况下,fromDegrees从0开始,意味着从当前状态开始进行旋转,大于0向右旋转,小于0向左旋转
共同属性:
1》duration 动画执行的时间
2》repeatCount 动画执行的次数 -1代表无限循环
3》repeatMode 动画执行的模式 restart 代表从头开始,reverse 代表反向旋转。注意repeatMode产生作用的前提条件是repeatCount大于0
4》interpolator :插入器(三种)
accelerate_decelerate_interpolator 加速-减速 动画插入器
accelerate_interpolator 加速-动画插入器
decelerate_interpolator 减速- 动画插入器
4》fillAfter 动画结束后停留在最后一帧
5》fillBefore 动画结束后停留在第一帧
6》<set/> 让多个动画同时执行
7》startOff 动画延时执行
使用的时候也很简单:
Animation animation = AnimationUtils.loadAnimation(this,R.anim.scale); showImage.startAnimation(animation);
这里我就不把完整的代码贴出来了,后面我会把我的项目源码贴上去,大家可以下载下来运行就知道了。
帧动画
我感觉帧动画是三种动画里面最容易的一种,因此我不打算去细讲,直接贴吧。
1)首先是在res/anim新建一个xml文件
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">
<item
android:drawable="@mipmap/coins6"
android:duration="100"/>
<item
android:drawable="@mipmap/coins5"
android:duration="100"/>
<item
android:drawable="@mipmap/coins4"
android:duration="100"/>
<item
android:drawable="@mipmap/coins3"
android:duration="100"/>
<item
android:drawable="@mipmap/coins2"
android:duration="100"/>
<item
android:drawable="@mipmap/coins1"
android:duration="100"/>
</animation-list>
2)在代码里面直接引用
ImageView animationImg1 = (ImageView) findViewById(R.id.animation1);
animationImg1.setImageResource(R.drawable.frame_anim1);
AnimationDrawable animationDrawable1 = (AnimationDrawable) animationImg1.getDrawable();
animationDrawable1.start();
好了,帧动画到这里就over了
属性动画:(Android 3.0之后才有的)
很多同学在刚开始使用属性动画的时候都会有一个疑问,在平时的开发过程中,好像我们很少使用属性动画,大部分的时候使用补间动画和帧动画就可以实现效果了。对的,刚开始的时候我也会有这个疑问,但是这些动画仅仅只是限于一些比较简单的动画,如果我们想实现一个比较炫酷的效果,属性动画是必不可少的。而且使用属性动画还有一个好处就是视图的点击位置随着内容位置的改变而改变,我想这是属性动画最大的好处之一,当然,属性动画还有很多很多的好处,这就需要同学们在实际的开发过程中自己去领会了,这里我就不做说明了。
首先我们来了解一下属性动画一些基本的API
1.Duration动画的持续时间,默认300ms
2.Time interpolation:时间差值,乍一看不知道是什么,但是我说LinearInterpolator、AccelerateDecelerateInterpolator,大家一定知道是干嘛的了,定义动画的变化率
3.RepeatCount:重复次数
4.RepeatMode: restart重新从头开始执行;reverse反方向执行
5.AnimatorSet:动画集,他的取值有两种:set.playTogether动画同步执行,set.playSequentially动画按顺序执行。例如:
AnimatorSet set = new AnimatorSet();
set.playTogether(alphaAnim, scaleXAnim, scaleYAnim, rotateAnim, transXAnim, transYAnim); // 动画同步执行
//set.playSequentially(alphaAnim, scaleXAnim, scaleYAnim, rotateAnim, transXAnim, transYAnim); // 动画按顺序执行
6.setStartDelay:动画延迟几秒后执行
7.TypeEvaluator:这是属性动画当中非常重要的一个属性,使用这个属性的最大作用是实现平滑过度的效果。
例如需要实现一个自由落体的效果:
ValueAnimator valueAnimator = new ValueAnimator();
valueAnimator.setDuration(3000);
valueAnimator.setObjectValues(new PointF(0,0));
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.setEvaluator(new TypeEvaluator<PointF>() {
@Override
public PointF evaluate(float fraction, PointF pointF, PointF t1) {
PointF point = new PointF();
point.x = 200 * fraction * 3;
point.y = 0.5f * 200 * (fraction * 3) * (fraction * 3);
return point;
}
});
valueAnimator.start();
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
PointF p = (PointF) valueAnimator.getAnimatedValue();
aImage.setX(p.x);
aImage.setY(p.y);
}
});
在这个简单Demo里面我们就需要使用到TypeEvaluator,其中fraction是动画完成度,pointF是动画的初始值,t1是动画的结束值,我们可以通过动画的完成度来时时刻刻记录下来视图的位置,从而实现动画的平滑过度。
属性动画有两个关键API:ObjectAnimator和ValueAnimator
ObjectAnimator比较简单
ObjectAnimator//
.ofFloat(view, "rotationX", 0.0F, 360.0F)//
.setDuration(500)//
.start();
看这个例子大家肯定就很清楚了,view是动画作用的视图,rotationX是动画的属性(即该view以X轴为对称点进行360度的旋转)
ValueAnimator和ObjectAnimator有点区别,我先贴下使用ValueAnimator
ValueAnimator animator = ValueAnimator.ofFloat(0, mScreenHeight
- mBlueBall.getHeight());
animator.setTarget(mBlueBall);
animator.setDuration(1000).start();
给你的感觉是不是,坑爹啊,这和ValueAnimator有毛线区别~但是仔细看,你看会发现,没有设置操作的属性~~也就是说,上述代码是没有任何效果的,没有指定属性~这就是和ValueAnimator的区别之处:ValueAnimator并没有在属性上做操作,这样做的好处是不需要操作的对象的属性一定要有get和set方法,你可以自己根据当前动画的完成度来设置效果,设置任何属性,这样就大大的提高了动画的灵活性。例如上面的实现抛物线的功能就是根据动画的完成度来实时刷新界面从而达到动画的效果。