欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android属性动画优化

程序员文章站 2022-05-04 08:11:39
...

属性动画优化

思路:

①使用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