Android 属性动画

Android 属性动画

大鱼 6,265 2020-09-16

一.基本信息

属性动画的优点

不再局限于View对象,无对象也可以进行动画处理
不再局限于四种基本变换:平移,旋转,缩放,透明度
可以灵活的操作任意对象属性,根据自己的业务来实现自己想要的结果

核心点

ObjectAnimator 对象动画
ValueAnimator 值动画
PropertyValueHolder 用于同时执行多个动画
TypeEvaluator 估值器
AnimatorSet 动画集合
Interpolator 差值器

二.代码示例

1. 使用ObjectAnimator完成在一段时间内透明度的变化

  /**
     * ObjectAnimator基本使用继承子ValueAnimator
     * 对对象v的alpha参数进行操作,alpha的值从1.0变到0.3
     *
     * @param v
     */
    public void startObjectAnimatorAnim(View v) {
        ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(v, "alpha", 1.0f, 0.3f);
        //执行事件
        alphaAnim.setDuration(1000);
        //延迟
        alphaAnim.setStartDelay(300);
        alphaAnim.start();
    }

2. 使用ValueAnimator完成在一段事件内缩放

    /**
     * 在一段时间内生成连续的值完成view的缩放
     * @param v
     */
    public void startValueAnimatorAnim(final View v) {
        //不改变属性大小,只在一段事件内生成连续的值
        ValueAnimator animator = ValueAnimator.ofFloat(0f, 100f);
        animator.setDuration(500);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                //百分比对应的值
                float value = (float) animation.getAnimatedValue();
                Log.e("TAG", "onAnimationUpdate: " + value);
                v.setScaleX(0.5f + value / 200);
                v.setScaleY(0.5f + value / 200);
            }
        });
        animator.start();
    }

3. 使用PropertyValueHolder完成上面的俩个动画同时执行

  /**
     * 一个动画实现多个效果的变换
     *
     * @param v
     */
    public void startPropertyValueHolderAnim(View v) {
        PropertyValuesHolder alphaProper = PropertyValuesHolder.ofFloat("alpha", 0.5f, 1f);
        PropertyValuesHolder scaleXProper = PropertyValuesHolder.ofFloat("scaleX", 0.5f, 1f);
        PropertyValuesHolder scaleYProper = PropertyValuesHolder.ofFloat("scaleY", 0.5f, 1f);
        ValueAnimator animator = ObjectAnimator.ofPropertyValuesHolder(v, alphaProper, scaleXProper, scaleYProper);
        animator.setDuration(500);
        animator.start();
    }

4. AnimatorSet多个动画按制定顺序执行

    /**
     * 执行多个动画并控制动画顺序
     *
     * @param v
     */
    public void startAnimatorSet(View v) {
        ObjectAnimator animator1 = ObjectAnimator.ofFloat(v, "translationX", 0f, 100f);
        ObjectAnimator animator2 = ObjectAnimator.ofFloat(v, "alpha", 0f, 1f);
        ObjectAnimator animator3 = ObjectAnimator.ofFloat(v, "scaleX", 0f, 1f);
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.setDuration(500);
        //动画1,2同时执行
        animatorSet.play(animator1).with(animator2);
        //动画2执行完成后执行动画3
        animatorSet.play(animator3).after(animator2);
        animatorSet.start();
    }
	animatorSet.play(animator1).with(animator2);动画1和动画2同时执行
	animatorSet.play(animator3).after(animator2);动画3在动画2执行完成后执行				animatorSet.playSequentially(animator1,animator2,animator3)动画1,2,3按顺序执行
	animatorSet.playTogether(animator1,animator2,animator3)三个动画同时执行

5. 插值器使用

估值器可以自定义变换规则,普通动画是匀速执行
    /**
     * 使用估值器实现重力下落
     *
     * @param v
     */
    public void startEvaluator(final View v) {
        ValueAnimator animator = new ValueAnimator();
        animator.setDuration(3000);
        animator.setObjectValues(new PointF(0, 0));
        final PointF pointF = new PointF();
        animator.setEvaluator(new TypeEvaluator() {
            @Override
            public Object evaluate(float fraction, Object startValue, Object endValue) {
                //fraction是运动中的匀速变化的值
                //根据重力计算实际的运动y=vt=0.5*g*t*t
                //g越大效果越明显
                pointF.x = 100 * (fraction * 5);
                pointF.y = 0.5f * 300f * (fraction * 5) * (fraction * 5);
                return pointF;
            }
        });
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                PointF p = (PointF) animation.getAnimatedValue();
                v.setX(p.x);
                v.setY(p.y);
            }
        });
        animator.start();
    }

6. 已经定义好计算规则的估值器(API中已经定义好了算法)



        //加速查值器,参数越大,速度越来越快
        animator.setInterpolator(new AccelerateInterpolator(10));
        //减速差值起,和上面相反
        animator.setInterpolator(new DecelerateInterpolator(10));
        //先加速后减速插值器
        animator.setInterpolator(new AccelerateDecelerateInterpolator());
        //张力值,默认为2,T越大,初始的偏移越大,而且速度越快
        animator.setInterpolator(new AnticipateInterpolator(3));
        //张力值tension,默认为2,张力越大,起始时和结束时的偏移越大
        animator.setInterpolator(new AnticipateOvershootInterpolator(6));
        //弹跳插值器
        animator.setInterpolator(new BounceInterpolator());
        //周期插值器
        animator.setInterpolator(new CycleInterpolator(2));
        //线性差值器,匀速
        animator.setInterpolator(new LinearInterpolator());

三. 插值器工具

根据计算公式,可视化地查看效果

http://inloop.github.io/interpolator/

DEDE6FA14B8945BE9A7740150CD4B2D7.png