recyclerView 中的某些项目未调用 doOnPreDraw 方法

Lor*_*nto 7 animation android visibility android-recyclerview

我在回收器视图中的某些动画时遇到问题。我在onViewAttachedToWindow中做了相关测量:

override fun onViewAttachedToWindow(holder: PairingViewHolder) {
        super.onViewAttachedToWindow(holder)

        // get originalHeight & expandedHeight if not gotten before
        if (holder.expandedHeight < 0) {
            // Execute pending bindings, otherwise the measurement will be wrong.
            holder.itemViewDataBinding.executePendingBindings()
            holder.cardContainer.layoutParams.width = expandedWidth
            holder.expandedHeight = 0 // so that this block is only called once

            holder.cardContainer.doOnLayout { view ->

                holder.originalHeight = view.height
                holder.expandView.isVisible = true

                // show expandView and record expandedHeight in next layout pass
                // (doOnPreDraw) and hide it immediately.
                view.doOnPreDraw {
                    holder.expandedHeight = view.height
                    holder.expandView.isVisible = false
                    holder.cardContainer.layoutParams.width = originalWidth
                }
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

问题是 doOnPreDraw 仅为某些视图而被调用。我猜这与视图的可见性有关,因为项目(展开)越小,调用 onPreDraw 的项目数就越高。

我的猜测是,由于我在 onLayout 中展开它们,因此 recyclerView 认为仅那些展开时在屏幕上实际可见的部分可见。在 onPreDraw 中,我折叠了它们,导致一些视图能够正确地设置动画,而另一些则不能。

你会如何解决这个问题?

提前致谢。

Poz*_*pps 0

我有同样的问题,并且能够弄清楚。

发生了什么: 只有最初在回收器视图上不可见的第一个项目对我来说确实受到影响,所有其他项目的行为都按预期进行。

导致它的原因: doOnPreDraw使用OneShotPreDrawListener,并且只有在onPreDraw被调用或被onViewDetachedFromWindow调用时才会分离。这是作为参考
的文档。doOnDetach

当该视图与窗口分离时执行给定的操作。如果视图未附加到窗口,则操作将立即执行,否则操作将在视图与当前窗口分离后执行。

在回收器视图上,我们最初创建与窗口分离的视图,这意味着它将onViewDetachedFromWindow立即被调用。
对于已经可见的视图,这不是问题,因为onPreDraw也立即被称为。
但对于尚不可见的视图,onPreDraw侦听器将在运行之前被删除。

免责声明:我尝试了多种更简单的不同解决方案,但我总是遇到一些边缘情况,因此唯一似乎可以正常工作的解决方案如下。(但如果有人找到更简单的,我会很高兴)。

解决方案: 我已经复制了整个方法OneShotPreDrawListenerremoveListeneronViewDetachedFromWindow方法中删除了。
遗憾的是我无法延长课程,因为课程已结束。