Android动画应用---自定义属性动画

    在上篇博客中对Android动画的基本使用方法做了简介,下面学习下Android自定义属性动画。自定义Android属性动画中涉及两个关键类TypeEvaluator和TimeInterpolator ,这两个都是接口类型,下面分别介绍这个两个类型:

    一、TypeEvaluator 估值器

    1、作用

    告诉动画系统,如何从属性初始值过渡到属性结束值。Android系统中提供的估值器有:ArgbEvaluator, FloatArrayEvaluator, FloatEvaluator, IntArrayEvaluator, IntEvaluator, PointFEvaluator, RectEvaluator。从类名称可以看出都对应什么样的属性。

    自定义TypeEvaluator时需要实现evaluate()方法,下面先看下IntEvaluator的关键代码,指定属性类型为Integer对象:

[java]  view plain  copy
  1. public class IntEvaluator implements TypeEvaluator<Integer> {  
  2.   
  3. public Integer evaluate(float fraction, Integer startValue, Integer endValue) {  
  4.         int startInt = startValue;  
  5.         return (int)(startInt + fraction * (endValue - startInt));  
  6.     }  
  7. }  
  • fraction:分数(0~1),用于表示动画的完成度的。像数学中斜率的概念。
  • startValue:动画的初始值。
  • endValue:动画的终止值。

    在看下RectEvaluator的关键代码,逻辑很简单:

[java]  view plain  copy
  1. public class RectEvaluator implements TypeEvaluator<Rect> {  
  2.     @Override  
  3.     public Rect evaluate(float fraction, Rect startValue, Rect endValue) {  
  4.         int left = startValue.left + (int) ((endValue.left - startValue.left) * fraction);  
  5.         int top = startValue.top + (int) ((endValue.top - startValue.top) * fraction);  
  6.         int right = startValue.right + (int) ((endValue.right - startValue.right) * fraction);  
  7.         int bottom = startValue.bottom + (int) ((endValue.bottom - startValue.bottom) * fraction);  
  8.         if (mRect == null) {  
  9.             return new Rect(left, top, right, bottom);  
  10.         } else {  
  11.             mRect.set(left, top, right, bottom);  
  12.             return mRect;  
  13.         }  
  14.     }  
  15. }  

2、自定义TypeEvaluator 

    自定义TypeEvaluator时需要实现evaluate()方法,evaluate()方法中的逻辑基本上可以按下面的公式计算:

    startValue+ fraction * (endValue - startValue)

    上面的公式只是一种表达形式,要看startValue和endValue 是什么对象,例如RectEvaluator先获取Rect的四个坐标,然后对四个坐标进行数学转换计算。这个fraction关键变量数值由谁决定?这个值由TimeInterpolator时间插值器来决定,TimeInterpolator定义动画的变换速率。下面来看下这个插值器。

二、TimeInterpolator 时间插值器

    1、作用

    时间插值器定义动画的变化率,这允许动画具有非线性运动,如加速和减速。这个插值器正决定了上面估值器中的fraction参数值。自定义TimeInterpolator 需要实现float getInterpolation(float input)方法,该方法的返回值决定了fraction。

    Android系统中提供的插值器类型有:

  • AccelerateDecelerateInterpolator:其变化率开始和结束缓慢,但通过中间加速;
  • AccelerateInterpolator:其变化率开始缓慢,然后加速;
  • AnticipateInterpolator:开始的时候向后然后向前甩;
  • AnticipateOvershootInterpolator:开始的时候向后,然后向前甩一定值后(超过endvalue)返回到最后的值,弹性回收的感觉;
  • BounceInterpolator:变化在最后时反弹,像皮球落地时的反弹;
  • CycleInterpolator:使用时指定动画循环次数。 变化率遵循正弦模式;
  • DecelerateInterpolator:其变化率开始快速然后减速;
  • LinearInterpolator:变化率以常亮数值变化;
  • OvershootInterpolator:向前甩一定值后再回到原来位置;
  • PathInterpolator:动画变化率和path的坐标有关,path的范围是[0~1]。

    Android提供的TimeInterpolator就这些,有兴趣的可以自行查看相关源码,下面分享下CycleInterpolator的实现代码:

    需要指定动画循环次数cycles,动画变化率是按正弦函数变化。

[java]  view plain  copy
  1. public class CycleInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {  
  2.     public CycleInterpolator(float cycles) {  
  3.         mCycles = cycles;  
  4.     }  
  5.   
  6.     public CycleInterpolator(Context context, AttributeSet attrs) {  
  7.         this(context.getResources(), context.getTheme(), attrs);  
  8.     }  
  9.   
  10.     /** @hide */  
  11.     public CycleInterpolator(Resources resources, Theme theme, AttributeSet attrs) {  
  12.         TypedArray a;  
  13.         if (theme != null) {  
  14.             a = theme.obtainStyledAttributes(attrs, R.styleable.CycleInterpolator, 00);  
  15.         } else {  
  16.             a = resources.obtainAttributes(attrs, R.styleable.CycleInterpolator);  
  17.         }  
  18.   
  19.         mCycles = a.getFloat(R.styleable.CycleInterpolator_cycles, 1.0f);  
  20.         setChangingConfiguration(a.getChangingConfigurations());  
  21.         a.recycle();  
  22.     }  
  23.   
  24.     public float getInterpolation(float input) {  
  25.         return (float)(Math.sin(2 * mCycles * Math.PI * input));  
  26.     }  
  27.   
  28.     private float mCycles;  
  29.   
  30.     /** @hide */  
  31.     @Override  
  32.     public long createNativeInterpolator() {  
  33.         return NativeInterpolatorFactoryHelper.createCycleInterpolator(mCycles);  
  34.     }  
  35. }  

2、自定义TimeInterpolator 

    自定义TimeInterpolator需要实现float getInterpolation(float input),而这个方法的实现就需要用到你的数学函数知识了,自己可以脑洞打开应用各种函数。下面自己自定义个TimeInterpolator实现先减速后加速:

[java]  view plain  copy
  1. public class MyInterpolator implements Interpolator {  
  2.     @Override  
  3.     public float getInterpolation(float input) {  
  4.         return ((4*input-2)*(4*input-2)*(4*input-2))/16f + 0.5f;  
  5.     }  
  6. }  

   自定属性就是自定义并实现上面两个类的相关方法,主要涉及一些数学知识点。望有所帮助~

猜你喜欢

转载自blog.csdn.net/white_wt/article/details/80576772