为什么这个共享元素视图在共享元素转换结束后没有被自动删除?
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)
。这导致共享元素视图保留在后面。
我有 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)
。这导致共享元素视图保留在后面。