如何解决抽屉动画期间的显示撕裂问题

时间:2015-12-18 16:04:18

标签: android animation android-recyclerview compositing

我使用第三方抽屉,允许底部和顶部抽屉(https://gist.github.com/patrickfav/6284130 MultipleOrientationSlidingDrawer)。

当我为抽屉打开动画时,我会在显示器上撕裂,但仅限于特殊情况。单击抽屉头时,动画流畅美观。

我在主窗口中有一个RecyclerView。如果用户单击列表视图中的条目,则抽屉滑动打开,显示所选条目的详细信息(单击轨道,从底部向上滑动介质控件)。抽屉动画的一部分是在抽屉打开时将主窗口内容淡化为黑色。因此,重大透支正在进行中。奇怪的是,当通过点击RecyclerView触发动画时,我会在动画期间撕裂显示屏(严重闪烁,大约发生在距离屏幕顶部2/3处)。

我正在寻找关于如何进行的建议:如何调试,或者在动画期间可能导致显示闪烁的理论。

这是我迄今为止所尝试的内容。

最初,我虽然这是由RecyclerView条目中的RippleDrawable动画引起的(在印刷机上和用于表示选择的激活更改。为了防止这种情况,我试图通过调用取消波纹动画recylerView.jumpDrawablesToCurrentState()在各个点(动画开始,以及每次动画更新期间)。据我所知,RippleDrawable动画已被有效取消。但显示翻录仍然会发生。事情有点复杂。状态更改动画在发生某种类型的发送之前不会被触发;但是在可绘制状态更改完成之后,对startAnimation的调用似乎也不会发生。所以我想我已经完成了这是对的。以防万一,我在每次动画传递过程中都试过调用recyclelerView.jumpDrawablesToCurrentState,这肯定会取消可绘制的动画。仍然没有快乐。

我已经推迟了对点击本身的响应,直到抽屉打开动画完成,因此在动画发生时没有主要的背景或前景操作。也没有音频运行,没有服务活动可言。分析表明,在动画运行时,没有运行的代码与绘图无关。

由于一切都发生得相对较快,因此很难准确地说出发生了什么,除了那些严重的闪烁之外。由于涉及动画,因此无法在动画中间中断调试器以查看正在进行的操作。一旦我进入调试器,下一次重绘将处于完全打开状态,因为动画位置来自当前设备uptimeMillis()。

如果我对动画进行概要分析,我会看到大量的文本布局操作,这表明回收者视图条目可能会在动画期间不断执行布局。这并不是真的有意义。没有理由我能想到布局的发生。它可能只是文本调用与onDraw操作有关。但我提到这一点是因为我在剖析中看到的看起来有点奇怪。动画期间的大部分CPU时间似乎都用于执行文本测量操作,大概是用于RecyclerView条目中的内容。

发生了大量的透支。抽屉本身有一个包含专辑封面的大位图,而且我可能已经堆叠了半透明的图层和背景。例如RecyclerView中各个条目的RippleDrawable背景很可能导致大部分屏幕完全透支。此外,视图还有一个完整的透视图,当抽屉动画显示为打开位置时,它会使背景内容变暗。话虽这么说,当点击抽屉的标题触发动画时,抽屉会动画很漂亮。只是当启动动画的点击来自RecyclerView时。所以我不认为透支是真正的问题。

对于它的价值,显示撕裂的位置似乎与选择和按压发生的位置无关。单击RecyclerView中的第一个或最后一个条目不会影响显示撕裂的位置。 ADB shell dumpsys SurfaceFlinger指示正在三层(状态栏,导航栏和主活动)上执行硬件组合。因此抽屉本身不使用SurfaceFlinger组合(如果它至少发生在导致显示器撕裂的方向上)。但是,在动画运行时,我无法真正获得SurfaceFlinger状态。在动画期间可能正在使用硬件合成。它确实看起来像显示翻录,我无法想象如果SurfaceFLinger没有进行合成,为什么会发生翻录。

我对问题可能是什么或试图调试这个问题的方法完全不知所措。关于一般调试方法的任何建议,或者对问题原因的建议可能会非常感激。

1 个答案:

答案 0 :(得分:0)

描述的撕裂发生在哪一层?是抽屉本身还是抽屉后面的布局?

无论哪种方式,我都有一些建议:

  1. 有时候过度绘制可能会出现问题,特别是在布局复杂的情况下 - 我特意在GoogleMaps Fragments上遇到了问题。在我的情况下解决这个问题的是创建一个简单的透明叠加来强制过度绘制,如下所示:

    <FrameLayout for drawer....>
    
    <View
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/transparent" />
    
    <LinearLayout w/ fragments etc..../>
    
    </FrameLayout>
    
  2. 抽屉动画因其预期目的而臭名昭着......在布局过渡期间,它们会像疯了一样滞后。我知道你说你在做任何事之前都确定抽屉动画完成了,但这值得仔细检查。出于这个原因,我个人将所有导航代码放在OnDrawerClosed()方法中,并使用itemSelected()代码设置标志并关闭抽屉。