如何减少动画中的requestLayout()滞后?

时间:2018-10-05 18:40:55

标签: android performance android-layout optimization drawing

我正在尝试设置TextView的宽度的动画,在我的Redmi Note 4上,它可以完美地工作。但是,当在速度稍慢的手机(1.2 GHz四核)上进行测试时,该动画则显得滞后。

经过一些入门调试之后,发现调用requestLayout()是罪魁祸首,它丢了许多帧,经过进一步检查,发现onMeasure(),这是重画时首先调用的方法,仅动画1个TextView就被称为“很多”。父级层次结构的其余部分可能将其称为bubblin'到根。

在我看来,这绝对不是布宜诺斯艾利斯。我正在尝试设置宽度和高度的动画。我使用ValueAnimator并在requestLayout内部调用onAnimationUpdate(),我尝试仅在其中一个内部调用requestLayout(),但这几乎没有任何作用。

final ViewGroup.LayoutParams layoutParams = container.getLayoutParams();

ValueAnimator anim = ValueAnimator.ofInt(this.width, ((int) (this.screenWidth / 1.5)));
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator valueAnimator) {
        layoutParams.width = (int) (Integer) valueAnimator.getAnimatedValue();
    }
});
anim.setDuration(duration);
anim.start();

anim = ValueAnimator.ofInt(this.height, this.screenHeight / 2);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator valueAnimator) {
        layoutParams.height = (int) (Integer) valueAnimator.getAnimatedValue();
        container.requestLayout();
    }
});
anim.setDuration(duration);
anim.start();

我尝试制作一个自定义StaticLayout来利用这种方法的效率和性能优化,但也无济于事。毕竟View类本身就是在反复调用onMeasure(),所以如何防止这种情况,只更新我愿意调整大小的TextView?当然invalidate()不起作用,因为它将错过调整大小的工作。

2 个答案:

答案 0 :(得分:0)

我认为这取决于设备的图形渲染功能。 因此,您将获得不同的设备。 如果有掉落的帧,则不应使它惊奇。

一个原因可能是:  -您正在从一定的宽度动画到screenWidth / 1.5,我认为这是很大的。

假设您的动画从48到480

初始值:48

finalValue:480

持续时间:200ms

表示(480-48)= 432步/在200毫秒内重新绘制 然后大约每毫秒2次抽奖。

因此,您为1张图纸提供的时间少于毫秒。 理想情况下,如果抽奖时间超过16ms,则存在帧丢失。 就您而言,由于requestLayout调用,您正在尝试过多的重画。

绘制432帧的理想条件是:

1 frame -> 20 ms (some extra time given) 432 frames -> 8640 ms

尝试减少对requestLayout的调用次数,以防止onMeasure()调用。

答案 1 :(得分:0)

经过一番挖掘,我发现在beginDelayedTransition()上使用ConstraintSetConstraintLayout会比手动动画更加有效和流畅。