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方法会取消掉动画,所以不会导致内存泄露。
补充建议:
- 尽量不要在刷新时做耗时操作,必须准备数据,创建图片,图片变换等,数据和图片都应该在之前就加载到内存中,图片变换用canvas的变换来实现。
- 同一个界面中多个动画重叠出现时,尽量将动画的刷新过程统一进行刷新,避免频繁的invalidate,尤其是多个动画有时序上的关系时更应该统一。
- 尽量使用带有参数的invalidate来刷新,这样可以减少很多运算量。
- 合理的环境下使用surfaceview来操作,比如播放视频等,这种刷新耗时比较大的情况。
- 开启硬件加速,硬件加速由于采用了显示列表的概念,所以刷新过程也有很大的优化,但是会增加额外的8M内存占用。
属性动画使用方法详解 可以参考郭霖大神的博客:https://blog.csdn.net/guolin_blog/article/details/43536355