Android属性动画ViewPropertyAnimator、

2019-02-18  本文已影响0人  飞奔吧牛牛

属性动画的三种方式

1.ViewPropertyAnimator
直接使用View.animate() 获取 ViewPropertyAnimator 对象,只能使用api提供的动画,总体来说有四类:
animate.translationX(500);//平移
animate.alpha(0.6f);//透明度
animate.rotation(90);//旋转
animate.scaleX(0.1f);//缩放
2.ObjectAnimator

可以实现和上诉相同的功能,例如:

ObjectAnimator.ofFloat(tv, "translationX", 500).setDuration(2000).start();或
ObjectAnimator.ofFloat(tv, View.TRANSLATION_X, 500).setDuration(2000).start();

View中存在setter和getter方法的属性才可以进行动画。如View中存在setTranslationX()和getTranslationX()方法。
但有些属性是View中没有的,比如控件的宽度width,它存在于LayoutParam中。如果要对控件宽度进行动画处理应该怎么办呢?
1.可以使用包装类来提供这个属性。
第一步:

class MyViewWapper {
        private View v;

        public MyViewWapper(View v) {
            this.v = v;
        }

        public int getWidth() {
            return v.getLayoutParams().width;
        }

        public void setWidth(int width) {
            v.getLayoutParams().width = width;
            v.requestLayout();
        }
    }

第二步:

ObjectAnimator.ofInt(new MyViewWapper(tv), "width", 500).setDuration(2000).start();

2.如果是自定义View,直接将setter和getter写在类中即可。
注意:ObjectAnimator并不是去目标对象中找和“width”一样的同名成员变量,而是拼接setter和getter方法再调用,所以必须提供setWidth()/getWidth()方法。

ValueAnimator

使用ObjectAnimator可以对View中没有的属性做动画,只需要包装一个类,并提供对应的setter/getter方法。ValueAnimator可以求出两个值之间的变化值,并回调到方法中,我们在回调的方法中手动设置控件的属性即可。

ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 500);
        valueAnimator.setDuration(2000);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int animatedValue = (Integer) animation.getAnimatedValue();
                tv.getLayoutParams().width = animatedValue;
                tv.requestLayout();
            }
        });
        valueAnimator.start();

补充:鉴于手机开发者模式中可以设置:动画程序时长缩放为关闭动画,使得动画不能正常执行。
可以参考:https://blog.csdn.net/u011387817/article/details/78628956 解决。
意思是开发者选项中该设置改变了ValueAnimator类中的静态成员变量:
private static float sDurationScale = 1.0f;
只要通过反射重置为1.0f即可。

public class ValueAnimatorUtil {

    /**
     * 如果动画被禁用,则重置动画缩放时长
     */
    public static void resetDurationScaleIfDisable() {
        if (getDurationScale() == 0)
            resetDurationScale();
    }

    /**
     * 重置动画缩放时长
     */
    public static void resetDurationScale() {
        try {
            getField().setFloat(null, 1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static float getDurationScale() {
        try {
            return getField().getFloat(null);
        } catch (Exception e) {
            e.printStackTrace();
            return -1;
        }
    }

    @NonNull
    private static Field getField() throws NoSuchFieldException {
        Field field = ValueAnimator.class.getDeclaredField("sDurationScale");
        field.setAccessible(true);
        return field;
    }
}
上一篇下一篇

猜你喜欢

热点阅读