1

我正在使用允许底部和顶部边缘抽屉的第 3 方抽屉(https://gist.github.com/patrickfav/6284130 MultipleOrientationSlidingDrawer)。

当我为抽屉的打开设置动画时,我会得到显示撕裂,但仅在特定情况下。单击抽屉标题时,动画流畅美观。

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

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

这是我到目前为止所尝试的。

jumpDrawablesToCurrentState 在每个动画传递期间,这肯定应该取消可绘制动画。仍然没有喜悦。

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

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

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

发生大量透支。抽屉本身有一个包含专辑插图的大位图,而且我可能已经堆叠了半透明的图层和背景。例如,RecyclerView 中各个条目上的 RippleDrawable 背景很可能会导致大部分屏幕完全过度绘制。此外,当抽屉动画到打开位置时,视图有一个完整的过度绘制通道,它会使背景内容变暗。话虽如此,当通过单击抽屉的标题触发动画时,抽屉的动画效果非常好。只是不是当启动动画的点击来自 RecyclerView 时。所以我不认为透支是真正的问题。

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

我完全不知道问题可能是什么,或者尝试调试它的方法。任何关于一般调试方法的建议,或关于问题原因的建议都将不胜感激。

4

1 回答 1

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() 代码设置标志并关闭抽屉。

于 2015-12-18T16:26:56.757 回答