带有 RecyclerView 的 Fragment 中的 Android 10 (Q) 过渡共享元素视图卡在固定位置

Sim*_*iak 6 android android-transitions fragment-transitions

我通常自己解决问题,但这次我真的很生气,找不到合适的解决办法。

设想:

我有两个片段让我们说AB

片段 A 中,我从 Rest API 填充 RecyclerView(后来只有 RV)。

片段 B 中,我有 CollapsingToolbarLayout 的“详细视图”。

当我单击RV 中的项目时,我正在打开带有过渡的片段 B和一个共享元素,即AppCompatImageView,我在其中设置了本地可绘制对象。在片段 B 中CollapsingToolbarLayout 中的图像。

共享元素转换在片段 B 中有效 - 图像移动正确。当我单击后退按钮并且图像移回其在 RV 中的原始位置时,过渡也有效。

但是这里出现了一个我无法解决的问题。在两个片段中,特定图像都被卡在位置上,当我滚动 RV 或 CollapsingToolbarLayout 视图时,视图没有改变 - 在片段 A 中,滚动 RV 时图像没有移动,而在片段 B 中,图像在折叠/展开更改时没有隐藏。

有没有人遇到过这个问题,因为我不并且真的不理解这种行为。经过多年的发展,我从未发生过。

这是从片段 B 返回后片段 A 的屏幕截图

在这里,我正在执行带有转换的片段事务:

fun replaceFragmentWithTransition(context: Context,
                                          sharedElement: View,
                                          fm: FragmentManager?,
                                          layoutContainer: Int,
                                          fragment: Fragment,
                                          tag: String,
                                          addToBackStack: Boolean = false) {
            fragment.sharedElementEnterTransition = TransitionInflater.from(context).inflateTransition(R.transition.default_transition)
            fragment.sharedElementReturnTransition = TransitionInflater.from(context).inflateTransition(R.transition.default_transition)
            val ft = fm?.beginTransaction()
            ft?.addSharedElement(sharedElement, sharedElement.transitionName)
            if (addToBackStack) { ft?.addToBackStack(null) }
            ft?.replace(layoutContainer, fragment, tag)
            ft?.commit()
        }
Run Code Online (Sandbox Code Playgroud)

这里我在片段 A 中设置返回转换回调(在 onViewCreated 中调用):

setExitSharedElementCallback(object: SharedElementCallback() {
            override fun onMapSharedElements(names: MutableList<String>?, sharedElements: MutableMap<String, View>?) {
                Timber.d("onMapSharedElements")
                val vh = recyclerView.findViewHolderForAdapterPosition(selectedPanelIndex)
                if (vh != null && sharedElements != null && names != null) {
                    Timber.d("Size: ${sharedElements.size}")
                    sharedElements[names[0]] = vh.itemView.findViewById(R.id.imagePanel)
                }
            }
        })
Run Code Online (Sandbox Code Playgroud)

在片段 B 中相同,但进入过渡(在 onViewCreated 中调用):

setEnterSharedElementCallback(object: SharedElementCallback() {
            override fun onMapSharedElements(names: MutableList<String>?, sharedElements: MutableMap<String, View>?) {
                Timber.d("onMapSharedElements")
                if (names != null && sharedElements != null) {
                    Timber.d("Size: ${sharedElements.size}")
                    sharedElements[names[0]] = imagePanel
                }
            }
        })
Run Code Online (Sandbox Code Playgroud)

在片段 B 中,我还在 onViewCreated 函数中将 transitionName 分配给 ImageView:

imagePanel.transitionName = transitionName
Run Code Online (Sandbox Code Playgroud)

并在 RV 适配器中设置动态转换名称:

inner class MyViewModel(override val containerView: View) : RecyclerView.ViewHolder(containerView), LayoutContainer {

        fun bind(item: Panel, callback: (Panel, View) -> Unit) {
            imagePanel.transitionName = "${containerView.context.getString(R.string.text_transition_name_panel_img)}_$adapterPosition"
            item.getDrawableFromType().takeIf { it > 0 }?.let {
                imagePanel?.setImageDrawable(containerView.context.getDrawableCompat(it))
                imagePanel.show()
            } ?: imagePanel.hide()
            textName?.text = item.name
            containerView.onClick { callback(item, imagePanel) }
        }
    }
Run Code Online (Sandbox Code Playgroud)

设备:Google Pixel 3、Android 10

请注意,如果我不使用转换回调,则返回转换不起作用,但片段 B 中的输入转换问题保持不变。

在这种情况下,我感到很失落。任何帮助将不胜感激。我尝试了很多东西。谢谢。


更新!:

似乎此问题仅与 Android 10 相关!我试过我的旧小米,它有效。我在这里创建了问题,所以希望它会得到解决。这真的很烦人。我会在这方面保持更新。

li2*_*li2 5

通过添加此库修复

implementation "androidx.transition:transition:1.3.0-beta01"
Run Code Online (Sandbox Code Playgroud)

版本 1.3.0-beta01

2019 年 10 月 9 日

新功能

  • 改进了与Fragment1.2.0-beta01的集成,以确保在转换完成之前不会破坏 Fragment 的视图,并在适当的时间取消转换。( aosp/1119841 )

版本 1.2.0

2019 年 10 月 9 日

自 1.1.0 版以来的重要变化

如果您的目标是 API 级别 29,则应使用此版本。否则,某些转换将无法正常工作。此版本使用 API 级别 29 中添加的新公共方法而不是反射调用。这是我们对非 SDK 接口工作的限制的一部分。

来源:https : //developer.android.com/jetpack/androidx/releases/transition#1.3.0-beta01