在上篇博客中对Android动画的基本使用方法做了简介,下面学习下Android自定义属性动画。自定义Android属性动画中涉及两个关键类TypeEvaluator和TimeInterpolator ,这两个都是接口类型,下面分别介绍这个两个类型:
一、TypeEvaluator 估值器
1、作用
告诉动画系统,如何从属性初始值过渡到属性结束值。Android系统中提供的估值器有:ArgbEvaluator, FloatArrayEvaluator, FloatEvaluator, IntArrayEvaluator, IntEvaluator, PointFEvaluator, RectEvaluator。从类名称可以看出都对应什么样的属性。
自定义TypeEvaluator时需要实现evaluate()方法,下面先看下IntEvaluator的关键代码,指定属性类型为Integer对象:
[java]view plain
copy
- public class IntEvaluator implements TypeEvaluator
{ - public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
- int startInt = startValue;
- return (int)(startInt + fraction * (endValue - startInt));
- }
- }
- fraction:分数(0~1),用于表示动画的完成度的。像数学中斜率的概念。
- startValue:动画的初始值。
- endValue:动画的终止值。
[java]view plain copy
- public class RectEvaluator implements TypeEvaluator
{ - @Override
- public Rect evaluate(float fraction, Rect startValue, Rect endValue) {
- int left = startValue.left + (int) ((endValue.left - startValue.left) * fraction);
- int top = startValue.top + (int) ((endValue.top - startValue.top) * fraction);
- int right = startValue.right + (int) ((endValue.right - startValue.right) * fraction);
- int bottom = startValue.bottom + (int) ((endValue.bottom - startValue.bottom) * fraction);
- if (mRect == null) {
- return new Rect(left, top, right, bottom);
- } else {
- mRect.set(left, top, right, bottom);
- return mRect;
- }
- }
- }
自定义TypeEvaluator时需要实现evaluate()方法,evaluate()方法中的逻辑基本上可以按下面的公式计算:
startValue+ fraction * (endValue - startValue)
上面的公式只是一种表达形式,要看startValue和endValue 是什么对象,例如RectEvaluator先获取Rect的四个坐标,然后对四个坐标进行数学转换计算。这个fraction关键变量数值由谁决定?这个值由TimeInterpolator时间插值器来决定,TimeInterpolator定义动画的变换速率。下面来看下这个插值器。
二、TimeInterpolator 时间插值器
【Android动画应用---自定义属性动画】1、作用
时间插值器定义动画的变化率,这允许动画具有非线性运动,如加速和减速。这个插值器正决定了上面估值器中的fraction参数值。自定义TimeInterpolator 需要实现float getInterpolation(float input)方法,该方法的返回值决定了fraction。
Android系统中提供的插值器类型有:
- AccelerateDecelerateInterpolator:其变化率开始和结束缓慢,但通过中间加速;
- AccelerateInterpolator:其变化率开始缓慢,然后加速;
- AnticipateInterpolator:开始的时候向后然后向前甩;
- AnticipateOvershootInterpolator:开始的时候向后,然后向前甩一定值后(超过endvalue)返回到最后的值,弹性回收的感觉;
- BounceInterpolator:变化在最后时反弹,像皮球落地时的反弹;
- CycleInterpolator:使用时指定动画循环次数。 变化率遵循正弦模式;
- DecelerateInterpolator:其变化率开始快速然后减速;
- LinearInterpolator:变化率以常亮数值变化;
- OvershootInterpolator:向前甩一定值后再回到原来位置;
- PathInterpolator:动画变化率和path的坐标有关,path的范围是[0~1]。
需要指定动画循环次数cycles,动画变化率是按正弦函数变化。
[java]view plain copy
- public class CycleInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {
- public CycleInterpolator(float cycles) {
- mCycles = cycles;
- }
- public CycleInterpolator(Context context, AttributeSet attrs) {
- this(context.getResources(), context.getTheme(), attrs);
- }
- /** @hide */
- public CycleInterpolator(Resources resources, Theme theme, AttributeSet attrs) {
- TypedArray a;
- if (theme != null) {
- a = theme.obtainStyledAttributes(attrs, R.styleable.CycleInterpolator, 0, 0);
- } else {
- a = resources.obtainAttributes(attrs, R.styleable.CycleInterpolator);
- }
- mCycles = a.getFloat(R.styleable.CycleInterpolator_cycles, 1.0f);
- setChangingConfiguration(a.getChangingConfigurations());
- a.recycle();
- }
- public float getInterpolation(float input) {
- return (float)(Math.sin(2 * mCycles * Math.PI * input));
- }
- private float mCycles;
- /** @hide */
- @Override
- public long createNativeInterpolator() {
- return NativeInterpolatorFactoryHelper.createCycleInterpolator(mCycles);
- }
- }
自定义TimeInterpolator需要实现float getInterpolation(float input),而这个方法的实现就需要用到你的数学函数知识了,自己可以脑洞打开应用各种函数。下面自己自定义个TimeInterpolator实现先减速后加速:
[java]view plain copy
- public class MyInterpolator implements Interpolator {
- @Override
- public float getInterpolation(float input) {
- return ((4*input-2)*(4*input-2)*(4*input-2))/16f + 0.5f;
- }
- }
自定属性就是自定义并实现上面两个类的相关方法,主要涉及一些数学知识点。望有所帮助~
推荐阅读
- Android自定义View
- ObjectAnimator使用
- Android自定义动画--放射菜单
- Android仿Keep运动休息倒计时圆形控件
- #|Android自定义View(带百分比的圆形进度条)