安卓动画学习(四) ---PropertyValuesHolder的介绍

安卓属性动画进阶PropertyValuesHolder与Keyframe

  • 可能大家都注意到了在ObjectAnimator和ValueAnimator中还有一个创建实例的方法ofPropertyValuesHolder()
  • 因为ObjectAnimator是继承自ValueAnimator的,我们就来学习一下ObjectAnimator.ofPropertyValuesHolder()吧,ValueAnimator的使用也类似
  • 这里说一下ofInt和其他一些of方法,他们在得到我们设置的参数之后,将我们这些参数进行包装成一个PropertyValuesHolder类实例,也就是说,这个类实例保存着我们这个动画的一些基本属性,我们在操动画的时候,其实就是操作这个类实例的
  • 那么到这里我们也就明白ofPropertyValuesHolder()这个方法的用处了吧,他让我们自己去构建自己的动画PropertyValuesHolder实例
    public static ObjectAnimator ofPropertyValuesHolder(Object target,PropertyValuesHolder... values)  
  • 下面我们就来看看这个类的用法

PropertyValuesHolder

  • 根据官方文档以及源码,这个类并没有向我们外放公开的构造方法,而是提供了一系列的生成类实例的静态方法,有兴趣可以去看官方文档,这里只简单说一下几个常用的
静态方法 方法说明
public static PropertyValuesHolder ofFloat(String propertyName, float... values) 构造并返回一个PropertyValuesHolder,其中包含一个给定的属性名称和一组浮点值。
public static PropertyValuesHolder ofInt(String propertyName, int... values) 构造并返回一个具有给定属性名称和一组int值的PropertyValuesHolder。
public static PropertyValuesHolder ofObject(String propertyName, TypeEvaluator evaluator,Object... values) 构造并返回一个PropertyValuesHolder,其中包含一个给定的属性名称和一组Object值。
public static PropertyValuesHolder ofKeyframe(String propertyName, Keyframe... values) 构造并返回一个PropertyValuesHolder对象,其中包含指定的属性名称和一组值。
  • 可以看到,在每个参数中基本都包括,要改变的属性名,和几组区间值,在给大家看一下第一个方法的源码
public static PropertyValuesHolder ofFloat(String propertyName, float... values) {
        return new FloatPropertyValuesHolder(propertyName, values);
    }
  • 他返回了一个PropertyValuesHolder的子类FloatPropertyValuesHolder,同理,在ofInt或者其他方法时也是返回不同类型的子类,这些个子类其实是PropertyValuesHolder的内部类,再跟进去看一下这个子类的参数吧
private static final HashMap<Class, HashMap<String, Long>> sJNISetterPropertyMap =
                new HashMap<Class, HashMap<String, Long>>();
        long mJniSetter;
        private FloatProperty mFloatProperty;

        Keyframes.FloatKeyframes mFloatKeyframes;
        float mFloatAnimatedValue;
  • 我这里把子类的所有参数放在这里,可以推测,他应该是通过那个Map来保存我们传进去的各个参数的,前面的class应该就是通过反射来拿到目标控件的set或者get方法的,到这里也就差不多了
  • 再结合
 public static ObjectAnimator ofPropertyValuesHolder(Object target,PropertyValuesHolder... values)  
  • 应该大概猜到这个方法是干什么用的了吧,他就跟我们之前讨论过的补间动画的set一样,把好多个动画包装起来,拿给一个控件用,于是就可以实现控件的多元化动画了
  • 看一下大概使用方法吧
    PropertyValuesHolder rotationHolder = PropertyValuesHolder.ofFloat("Rotation", 60f, -60f, 40f, -40f, -20f, 20f, 10f, -10f, 0f);  
    PropertyValuesHolder colorHolder = PropertyValuesHolder.ofInt("BackgroundColor", 0xffffffff, 0xffff00ff, 0xffffff00, 0xffffffff);  
    ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(mTextView, rotationHolder, colorHolder);  
    animator.setDuration(3000);  
    animator.setInterpolator(new AccelerateInterpolator());  
    animator.start();  
  • 不用解释,大家都明白
  • 对于PropertyValuesHolder还有ofObject创建动画的方法,其实还是将控制权交给了我们,用法都大同小异
  • 在看到动画包装类的参数的时候,大家有没有注意到Keyframes呢,谷歌为了方便我们控制动画速率,而不是每次去麻烦的自己写插值器,就为我们这些渣渣提供了这个类
  • 接下来看这个类

Keyframe

  • 我们在定义动画的时候,往往是指定几个定值,表示某个View的某个属性从一个值变到后值,那么这个keyframe表示的就是这个,不过他加上了时间这个概念,先看一下构造吧
    public static Keyframe ofFloat(float fraction, float value)  
  • fraction:表示当前的显示进度,即从加速器中getInterpolation()函数的返回值;
  • value:表示当前应该在的位置
  • 明白了吧,通过这样我们可以很轻松的控制动画的快慢
  • 那么我们需要怎么使用我们自己定义的时间值呢
  • 放心吧,安卓已经为我们弄好了,在动画的生成实例类中,有这么一个方法
    public static PropertyValuesHolder ofKeyframe(String propertyName, Keyframe... values)  
  • 嗯,为VIew中属性名叫这个(propertyName)那个属性按照我为你设置的规则(Keyframe)这么改变他的值
  • 看一下具体代码
Button button = findViewById(R.id.main_useKeyFrameViewBt);
        ImageView imageView = findViewById(R.id.main_useKeyFrameViewIv);
        Keyframe keyframe = Keyframe.ofFloat(0,0);
        Keyframe keyframe0 = Keyframe.ofFloat(0.3f,-200);
        Keyframe keyframe1 = Keyframe.ofFloat(0.5f,200);
        Keyframe keyframe2 = Keyframe.ofFloat(1f,100);
        PropertyValuesHolder holder = PropertyValuesHolder.ofKeyframe("translationY",keyframe,keyframe0
        ,keyframe1,keyframe2);

        final ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(imageView,holder);
        animator.setDuration(3000);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                animator.start();
            }
        });
  • 代码很简单,就是来回上下平移,不过移动的速度不同,理解用法即可
  • 说到这里,我将平时用的几个系统自带的属性列一下
alpharotationrotationXrotationY,translationX,translationY,scaleX,scaleY
  • 注意这里使用的还是驼峰命名法,大家在使用的时候或者自己定义属性的时候一定要注意
  • 那么到这里,关于这个就介绍完了,在valueAnimator其实也是一样的,可以类比

猜你喜欢

转载自blog.csdn.net/asffghfgfghfg1556/article/details/80443973