【问题标题】:FragmentContainerView does not (seem to) support shared elements transition on pre-L devicesFragmentContainerView 不(似乎)支持 pre-L 设备上的共享元素转换
【发布时间】:2020-05-07 14:47:33
【问题描述】:

我有一个MainActivity,其布局如下:

<androidx.fragment.app.FragmentContainerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/nav_host_fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:name="androidx.navigation.fragment.NavHostFragment"
    app:defaultNavHost="true"
    app:navGraph="@navigation/nav_graph_main"/>

其余的都在片段中。

我有两个片段,我在其中使用共享元素(例如列表片段和细节片段)为过渡设置动画。

我正在使用来自 JetPack 的 Navigation ComponentSafeArgs 插件以及来自 AndroidX 包的转换类。

val directions = AlbumsListFragmentDirections.actionAlbumsListFragmentToAlbumDetailsFragment(
            ViewCompat.getTransitionName(binding.imageThumbnail)!!
        )

val extras = FragmentNavigatorExtras(
            binding.imageThumbnail to ViewCompat.getTransitionName(binding.imageThumbnail)!!
        )

findNavController().navigate(directions, extras)

我还使用postponeEnterTransition()startPostponedEnterTransition() 在 UI 准备就绪时触发过渡动画。


在任何 L+ 设备上,由于共享元素转换是来自操作系统的本机组件,因此没有问题。

但是,在我的 KitKat 设备 (Samsung S4) 上,由于我的 min API 为 19,因此在使用以下崩溃日志调用上述代码 sn-p 时应用程序崩溃:

java.lang.IllegalStateException: Views added to a FragmentContainerView must be associated with a Fragment. View androidx.transition.GhostViewApi14{42a33b30 V.ED.... ......ID 0,0-0,0} is not associated with a Fragment.
        at androidx.fragment.app.FragmentContainerView.addView(FragmentContainerView.java:276)
        at android.view.ViewGroup.addView(ViewGroup.java:3557)
        at android.view.ViewGroup.addView(ViewGroup.java:3533)
        at androidx.transition.GhostViewApi14.addGhost(GhostViewApi14.java:53)
        at androidx.transition.GhostViewUtils.addGhost(GhostViewUtils.java:30)
        at androidx.transition.ChangeTransform.createGhostView(ChangeTransform.java:391)
        at androidx.transition.ChangeTransform.createAnimator(ChangeTransform.java:272)
        at androidx.transition.Transition.createAnimators(Transition.java:744)
        at androidx.transition.TransitionSet.createAnimators(TransitionSet.java:470)
        at androidx.transition.TransitionSet.createAnimators(TransitionSet.java:470)
        at androidx.transition.TransitionSet.createAnimators(TransitionSet.java:470)
        at androidx.transition.Transition.playTransition(Transition.java:1821)
        at androidx.transition.TransitionManager$MultiListener.onPreDraw(TransitionManager.java:300)
        at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:879)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2131)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1236)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6471)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:803)
        at android.view.Choreographer.doCallbacks(Choreographer.java:603)
        at android.view.Choreographer.doFrame(Choreographer.java:573)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:789)
        at android.os.Handler.handleCallback(Handler.java:733)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:157)
        at android.app.ActivityThread.main(ActivityThread.java:5356)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:515)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
        at dalvik.system.NativeStart.main(Native Method)

错误很容易理解:FragmentContainerView 不支持任何不与片段关联的视图。显然,这次崩溃的根源是 androidx.transition.GhostViewApi14

查看这个类的the source code,我了解到它是 L 中添加的原生视图的后向端口,以支持我相信的转换。

我试图通过在land-v19 中声明的MainActivity 的XML 文件中恢复到旧方式来解决该问题:

<fragment
    android:name="androidx.navigation.fragment.NavHostFragment"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/nav_host_fragment_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:defaultNavHost="true"
    app:navGraph="@navigation/nav_graph_main"/>

但是,该应用程序仍然在我的 KitKat 设备上崩溃。 框架是否有可能(可能是AppCompat - 我正在使用带有activity-ktx-1.1.0' 的稳定版本1.1.0?)自动将&lt;fragment&gt; 替换为FragmentContainerView? 看起来是这样,因为我删除了那个 XML 布局,并将其内容粘贴到了原始布局中。简而言之,所有版本都将使用带有&lt;fragment&gt;的XML

这是一个错误吗?如果是这样,应该报告还是已知? 还是我做错了什么?

感谢您的帮助!

【问题讨论】:

    标签: android android-fragments kotlin android-animation android-transitions


    【解决方案1】:

    我能够解决该特定问题,并在我的 KitKat 设备上完全运行过渡。

    当我在 Android 10 (Q) 设备上测试应用程序时,我偶然发现了这个 issue,其中的转换不起作用,但不会使应用程序崩溃。查看日志,它会看到来自 / 与 Ghost View API 的方法反射将失败,因为 Android 10 对反射逻辑施加了限制。

    我的问题也与那个Ghost View API有关。

    solution 由开发该 API 的开发人员提供,用于升级到修复了该特定问题的更新和稳定的 AndroidX Transition API 版本。

    在写这个答案的时候,最稳定的版本是1.3.1

    它解决了这两个问题。问题已解决。

    我很幸运偶然发现了这个问题,哪个解决方案可以解决我的问题!

    【讨论】:

      猜你喜欢
      • 2015-01-15
      • 2014-01-12
      • 2017-02-23
      • 2015-01-15
      • 2015-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多