为什么这个共享元素视图在共享元素转换结束后没有被自动删除?

Why is this Shared Element view not being automatically removed after the shared element transition ends?

我有 2 个 RecyclerViews - 概述和细节 RV。当用户单击 Overview RV 中的项目时,单击的视图将作为共享元素添加到 Fragment Transaction 中并转换为 Detail RV。

问题:

过渡的运动部分效果很好。但是,在转换完成后,共享元素视图不会从 Detail RV 中删除!当我滚动 Detail RV 时,我可以看到共享元素的 2 个实例!一个与其余内容一起滚动(这是我想要的),另一个停留在屏幕上的固定位置。只有当我将共享元素向外滚动并返回到 RV 的视口中,强制重新绑定时,不需要的共享元素才会消失。

是什么导致共享元素视图没有被自动删除?

代码:

这就是我将点击的视图添加为共享元素转换目标的方式。

// OverviewAdapter.kt:

view.setOnClickListener { view ->
    val sharedElements = getAllChildrenWithTransitionNames(view) // returns Map<String,View>

    supportFragmentManager.beginTransaction()
        .replace(R.id.fragmentContainer, DetailFragment())
        .addToBackStack(null)
        .also{ ft ->
            ft.setReorderingAllowed(true)
            sharedElements.forEach { (tn, view) ->
                ft.addSharedElement(view, tn)
            }
        }
        .commit()
}

这就是我在 DetailFragment 中准备共享元素过渡的方式。点击的item永远是DetailFragment中的第一个唯一item,所以保证被绘制。

// DetailFragment.kt
class DetailsTransition : TransitionSet() {
    init {
        addTransition(ChangeBounds())
        addTransition(ChangeTransform())
        addTransition(ChangeImageTransform())
    }
}

val listAnimator = MyRVItemAnimator()

override fun onCreate(saved: Bundle?){
    listAnimator.blockAnimations = true // Detail RV has an item animator. This blocks animations during transitions to prevent flicker
    sharedElementEnterTransition = DetailsTransition().also {
        it.addListener(
          onEnd = {
            listAnimator.blockAnimations = false
          }
        )
}


// DetailAdapter.kt
override fun onBindViewHolder(holder: VH, position: Int) {
    detailFragment.startPostponedEnterTransition()
}

我还确保所有 transitionNames 都是唯一且匹配的。那么为什么在过渡完成后共享元素 View 没有被自动删除?

原来我的 RV ItemAnimator 有一个错误。我在屏蔽动画的时候,没有调用dispatchAdd/RemoveFinished(holder)。这导致共享元素视图保留在后面。