动画学习笔记
参考学习文章:http://blog.csdn.net/harvic880925/article/details/50995268
动画技能树概述:
Tween Animation:
它由四种类型组成:alpha、scale、translate、rotate;
补间动画,其实对控件的真正的属性没有变化,它作用的是控件的画布,通过对画布的操作实现了对应的效果。由于是对画布的操作,所以它就只能支持画布对应的四种变化。
四种动画的共有操作
setDuration(long) 动画持续时间,以毫秒为单位
setFillAfter(boolean)如果设置为true,控件动画结束时,将保持动画最后时的状态
setFillBefore(boolean)如果设置为true,控件动画结束时,还原到开始动画前的状态
setFillEnabled(boolean)与android:fillBefore 效果相同,都是在动画结束时,将控件还原到初始化状态
setRepeatCount(int)重复次数
setRepeatMode(int)重复类型,有reverse和restart两个值,取值为RESTART或 REVERSE,必须与repeatCount一起使用才能看到效果。因为这里的意义是重复的类型,即回放时的动作。
setInterpolator(Interpolator) 设定插值器,其实就是指定的动作效果,比如弹跳效果等。(这个是动画很重要的东西)
AlphaAnimation
AlphaAnimation(floatfromAlpha, float toAlpha)
ScaleAnimation:
ScaleAnimation(floatfromX, float toX, float fromY, float toY)
ScaleAnimation(floatfromX, float toX, float fromY, float toY, float pivotX, float pivotY)
ScaleAnimation(floatfromX, float toX, float fromY, float toY, int pivotXType, float pivotXValue,int pivotYType, float pivotYValue)
RotateAnimation
RotateAnimation(floatfromDegrees, float toDegrees)
RotateAnimation(floatfromDegrees, float toDegrees, float pivotX, float pivotY)
RotateAnimation(floatfromDegrees, float toDegrees, int pivotXType, float pivotXValue, intpivotYType, float pivotYValue)
TranslateAnimation
TranslateAnimation(floatfromXDelta, float toXDelta, float fromYDelta, float toYDelta)
TranslateAnimation(intfromXType, float fromXValue, int toXType, float toXValue, int fromYType, floatfromYValue, int toYType, float toYValue)
AnimationSet
将几个动画结合成一个动画集。
AlphaAnimation alphaAnim = new AlphaAnimation(1.0f,0.1f);
ScaleAnimation scaleAnim = new ScaleAnimation(0.0f,1.4f,0.0f,1.4f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
RotateAnimation rotateAnim = new RotateAnimation(0, 720, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
AnimationSet setAnim=new AnimationSet(true);
setAnim.addAnimation(alphaAnim);
setAnim.addAnimation(scaleAnim);
setAnim.addAnimation(rotateAnim);
setAnim.setDuration(3000);
setAnim.setFillAfter(true);
Interpolator
插值器主要目的是通过控制动画的执行百分比,从而控制动画的一系列效果。下面列出的是差值动画系统默认给的一些插值器。
默认插值器:
AccelerateDecelerateInterpolator 在动画开始与介绍的地方速率改变比较慢,在中间的时候加速
AccelerateInterpolator 在动画开始的地方速率改变比较慢,然后开始加速
AnticipateInterpolator 开始的时候向后然后向前甩
AnticipateOvershootInterpolator 开始的时候向后然后向前甩一定值后返回最后的值
BounceInterpolator 动画结束的时候弹起
CycleInterpolator 动画循环播放特定的次数,速率改变沿着正弦曲线
DecelerateInterpolator 在动画开始的地方快然后慢
LinearInterpolator 以常量速率改变
OvershootInterpolator 向前甩一定值后再回到原来位置
自定义插值器:
自定义插值器这里通过控制返回的input的那个值从而控制动画索要操作的属性的百分比。这个可以在后面看valueAnimator的时候复写他的值监听的时候会比较常用到。
Evaluator
在讲到Interpolator的时候我们不得不再提一下Evaluator。这个和Interpolator是一个组合技,也就是说Interpolator中获取的是执行的百分比。而Evaluator则可以通过那个百分比,重新计算最终返回给动画索要执行的那个值。也就是预估值。
public class ReverseEvaluator implements TypeEvaluator<Integer> {
@Override
public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
int startInt = startValue;
return (int) (endValue - fraction * (endValue - startInt));
}
}
这里的fraction 是由Interpolator提供的。
Evaluator比较重要的一个估值器是颜色估值器ArgbEvaluator:
public class ArgbEvaluator implements TypeEvaluator {
public Object evaluate(float fraction, Object startValue, Object endValue) {
int startInt = (Integer) startValue;
int startA = (startInt >> 24);
int startR = (startInt >> 16) & 0xff;
int startG = (startInt >> 8) & 0xff;
int startB = startInt & 0xff;
int endInt = (Integer) endValue;
int endA = (endInt >> 24);
int endR = (endInt >> 16) & 0xff;
int endG = (endInt >> 8) & 0xff;
int endB = endInt & 0xff;
return (int)((startA + (int)(fraction * (endA - startA))) << 24) |
(int)((startR + (int)(fraction * (endR - startR))) << 16) |
(int)((startG + (int)(fraction * (endG - startG))) << 8) |
(int)((startB + (int)(fraction * (endB - startB))));
}
}
具体的流程是这样子的:
ValueAnimator
Tween Animation改变的是画布的属性,而ValueAnimator则是通过设定的起点值和终点值之间的一系列变化,让我们自己去控制控件所需要变化的某一属性或者某几样属性。它的目的其实是让动画和值关联起来,并不关心执行的是哪个控件。
OfFloat、OfInt()
ofInt()只能传入Integer类型的值,而ofFloat()则只能传入Float类型的值。
ValueAnimator animator = ValueAnimator.ofInt(0,600);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int curValue = (int)animation.getAnimatedValue();
tv.layout(tv.getLeft(),curValue,tv.getRight(),curValue+tv.getHeight());
}
});
animator.setDuration(1000);
animator.setInterpolator(new BounceInterpolator());
animator.start();
ValueAnimator可以设置的初始值有很多我们可以用.OfFloat、.OfInt()等控制取值的类型和范围。
ofObject()
对于非int和float值的传递,我们可以使用ofObject来搞定!
ValueAnimator animator = ValueAnimator.ofObject(new CharEvaluator(),new Character('A'),new Character('Z'));
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
char text = (char)animation.getAnimatedValue();
tv.setText(String.valueOf(text));
}
});
animator.setDuration(10000);
animator.setInterpolator(new AccelerateInterpolator());
animator.setEvaluator(new CharEvaluator());
animator.start();
public class CharEvaluator implements TypeEvaluator<Character> {
@Override
public Character evaluate(float fraction, Character startValue, Character endValue) {
int startInt = (int)startValue;
int endInt = (int)endValue;
int curInt = (int)(startInt + fraction *(endInt - startInt));
char result = (char)curInt;
return result;
}
}
ObjectAnimator
ValueAnimator有个缺点,就是只能对数值对动画计算。我们要想对哪个控件操作,需要监听动画过程,在监听中对控件操作。这样使用起来相比补间动画而言就相对比较麻烦。
为了能让动画直接与对应控件相关联,以使我们从监听动画过程中解放出来,谷歌的开发人员在ValueAnimator的基础上,又派生了一个类ObjectAnimator;
普通用法:
public static ObjectAnimator ofFloat(Object target, String propertyName, float... values)
第一个参数用于指定这个动画要操作的是哪个控件
第二个参数用于指定这个动画要操作这个控件的哪个属性
第三个参数是可变长参数,这个就跟ValueAnimator中的可变长参数的意义一样了,就是指这个属性值是从哪变到哪。像我们上面的代码中指定的就是将textview的alpha属性从0变到1再变到0;
ObjectAnimator animator = ObjectAnimator.ofFloat(tv,"rotation",0,180,0);
animator.setDuration(2000);
animator.start();
因为是对控件属性做控制,所以能够控制的细节的其实多:
//1、透明度:alpha
public void setAlpha(float alpha)
//2、旋转度数:rotation、rotationX、rotationY
public void setRotation(float rotation)
public void setRotationX(float rotationX)
public void setRotationY(float rotationY)
//3、平移:translationX、translationY
public void setTranslationX(float translationX)
public void setTranslationY(float translationY)
//缩放:scaleX、scaleY
public void setScaleX(float scaleX)
public void setScaleY(float scaleY)
绘制原理:
在ObjectAnimator中,则是先根据属性值拼装成对应的set函数的名字,比如这里的scaleY的拼装方法就是将属性的第一个字母强制大写后,与set拼接,所以就是setScaleY。然后通过反射找到对应控件的setScaleY(float scaleY)函数,将当前数字值做为setScaleY(float scale)的参数将其传入。
更具这个原理,我们很容易对我们自定义的对象的相关属性进行更改。
public class Point {
private int mRadius;
public Point(int radius){
mRadius = radius;
}
public int getRadius() {
return mRadius;
}
public void setRadius(int radius) {
mRadius = radius;
}
}
ObjectAnimator animator = ObjectAnimator.ofInt(mPointView, "pointRadius", 0, 300, 100);
animator.setDuration(2000);
animator.start();