6

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

设想:

我有两个片段,比如说AB

Fragment A 中,我正在从 Rest API 填充 RecyclerView(后来只有 RV)。

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

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

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

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

有没有人遇到过这个问题,因为我不理解,也真的不理解这种行为。经过多年的发展,从来没有发生在我身上。

这是从 Fragment B 返回后的 Fragment 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()
        }

在这里,我在 Fragment 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)
                }
            }
        })

在片段 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
                }
            }
        })

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

imagePanel.transitionName = transitionName

并且还在 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) }
        }
    }

设备:谷歌 Pixel 3、Android 10

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

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


更新!:

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

4

1 回答 1

5

通过添加此库修复

implementation "androidx.transition:transition:1.3.0-beta01"

版本 1.3.0-beta01

2019 年 10 月 9 日

新的功能

版本 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

于 2019-10-12T12:50:14.113 回答