Android属性动画优化

版权声明:本文为博主原创文章,转载请标明原文出处链接。 https://blog.csdn.net/iblade/article/details/82260435

属性动画优化

思路:

①使用PropertyValuesHolder 

②使用Keyframe 

③animator.setRepeatCount(ValueAnimator.INFINITE)及时cancel()

④动画卡顿,可以考虑使用自定义控件实现,如果一个自定义不行,那就是两个。。。(待续)

一,PropertyValuesHolder 

        
        float currentX = textView.getTranslationX();
        float currentY = textView.getTranslationY();
        //传统写法
        ObjectAnimator tX = ObjectAnimator.ofFloat(textView, "translationX", currentX, -300, currentX);
        ObjectAnimator tY = ObjectAnimator.ofFloat(textView, "translationY", currentY, 200, currentY);
        AnimatorSet set = new AnimatorSet();
        set.setDuration(1000);
        set.playTogether(tX, tY);//或者  set.play(tX).with(tY);
        set.start();

        //一个view同时发生多种效果时,建议使用PropertyValuesHolder,这样ObjectAnimator只有一个对象
        PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("translationX", currentX, 500, currentX);
        PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("translationY", currentY, 400, currentY);
        ObjectAnimator.ofPropertyValuesHolder(textView, pvhX, pvhY).setDuration(1000).start();

二,Keyframe 

//传统写法
        ObjectAnimator transYFirstAnim = ObjectAnimator.ofFloat(textView, "translationY", 0, 100);
        ObjectAnimator transYSecondAnim = ObjectAnimator.ofFloat(textView, "translationY", 100, 0);
        AnimatorSet animSet = new AnimatorSet();
        animSet.playSequentially(transYFirstAnim, transYSecondAnim);


        //一个view的单个属性先后发生一系列变化时,建议使用Keyframe达到效果。从词义上来理解Keyframe是关键帧
        Keyframe k0 = Keyframe.ofFloat(0f, 0); //第一个参数为“何时”,第二个参数为“何地”
        Keyframe k1 = Keyframe.ofFloat(0.5f, 100);
        Keyframe k2 = Keyframe.ofFloat(1f, 0);
        PropertyValuesHolder p = PropertyValuesHolder.ofKeyframe("translationY", k0, k1, k2);
        ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(textView, p);
        objectAnimator.start();
        /*
            效果就是:
         开始时 位置为0;
         动画开始1/2时 位置为100;
         动画结束时 位置为0。
         */

总结就是,如果是同一个view的一系列动画,均可使用以上组合方式达到只使用一个ObjectAnimator的效果 。多个view的动画用AnimatorSet进行动画组合和排序,代码架构和执行效率基本能达到最优化。

三,及时取消无限循环动画

许多时候用到了无限循环的动画,我们会这样写:animator.setRepeatCount(ValueAnimator.INFINITE); 
这样写如果没有及时取消,会导致此属性动画持有被动画对象的引用而导致内存泄露,故在activity生命周期结束时,如onDestroy方法中,及时的cancel掉这种动画。 
补间动画无此问题,它是给view做动画,在view的onDetachedFromWindow方法会取消掉动画,所以不会导致内存泄露。

补充建议:

  1. 尽量不要在刷新时做耗时操作,必须准备数据,创建图片,图片变换等,数据和图片都应该在之前就加载到内存中,图片变换用canvas的变换来实现。
  2. 同一个界面中多个动画重叠出现时,尽量将动画的刷新过程统一进行刷新,避免频繁的invalidate,尤其是多个动画有时序上的关系时更应该统一。
  3. 尽量使用带有参数的invalidate来刷新,这样可以减少很多运算量。
  4. 合理的环境下使用surfaceview来操作,比如播放视频等,这种刷新耗时比较大的情况。
  5. 开启硬件加速,硬件加速由于采用了显示列表的概念,所以刷新过程也有很大的优化,但是会增加额外的8M内存占用。

属性动画使用方法详解 可以参考郭霖大神的博客:https://blog.csdn.net/guolin_blog/article/details/43536355

猜你喜欢

转载自blog.csdn.net/iblade/article/details/82260435