如何减少动画中的 requestLayout() 延迟?

How to reduce requestLayout() lag in animations?

我正在尝试为 TextView 的宽度设置动画,在我的 Redmi Note 4 上它完美运行。然而,当在稍慢的 phone(1.2 GHz 四核)上进行测试时,动画非常滞后。

经过一些入门调试,原来调用requestLayout()是罪魁祸首,它丢了很多帧,进一步检查,结果是onMeasure()这是第一个重绘 时调用的方法被调用很多,因为只有 1 TextView 被动画化。父层次结构的其余部分可能将其称为 bubblin' 到根。

这对我来说绝对不是什么好事。我正在尝试为宽度和高度设置动画。我使用 ValueAnimator 并在 onAnimationUpdate() 中调用 requestLayout,我尝试仅在其中一个中调用 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 class 本身就是反复调用 onMeasure() 的东西,那么我怎样才能防止这种情况发生并且只更新我愿意调整大小的 TextView?当然 invalidate() 不会工作,因为它会错过调整大小的工作。

我认为这取决于设备的图形渲染能力。 所以你在设备上有所不同。 如果出现掉帧现象,请不要大惊小怪

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

假设您的动画从 48 变为 480

初始值:48

最终值:480

持续时间:200 毫秒

表示200毫秒内(480-48) = 432 steps/re-draw 然后,大约每毫秒绘制 2 次。

所以你给一张图不到一毫秒。 理想情况下,如果时间绘制时间超过 16 毫秒,则会出现丢帧。 在您的情况下,由于 requestLayout 调用,您尝试重新绘制的次数过多。

绘制 432 帧的理想条件如下:

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

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

经过一些挖掘,我发现在 ConstraintLayout 上使用 beginDelayedTransition()ConstraintSet 被证明比手动动画更高效、更流畅。