FragmentContainerView (кажется) не поддерживает переход общих элементов на устройствах pre-L - PullRequest
0 голосов
/ 07 мая 2020

У меня 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"/>

Остальные находятся во Фрагментах.

У меня есть два фрагмента, в которых я анимирую переход с помощью общих элементов, таких как фрагмент списка и фрагмент детали.

Я использую Navigation Component из JetPack с плагином SafeArgs рядом с с классами переходов из пакета 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() для запуска анимации переходов, когда пользовательский интерфейс готов к этому.


На любых устройствах L +, поскольку переходы общих элементов являются собственными компонентами ОС, проблем нет.

Однако на моем устройстве KitKat (Samsung S4), поскольку мой min API равен 19, приложение вылетает, когда вызов приведенного выше фрагмента кода с этими журналами cra sh:

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 на root этой cra sh.

Заглянув в исходный код этого класса, я узнал, что это резервный порт для собственного представления добавлен в L для поддержки переходов, как я полагаю.

Я попытался исправить эту проблему, вернувшись к старому способу, в файле XML для моего MainActivity, объявленного в land-v19:

<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 - я использую стабильную версию 1.1.0 с activity-ktx-1.1.0'?) Автоматически заменяет <fragment> на FragmentContainerView? Похоже так, потому что я удалил этот макет XML и вставил его содержимое в исходный. Проще говоря, все версии будут использовать это XML с <fragment>

. Это ошибка? Если да, то следует ли об этом сообщать или это известно? Или я что-то не так делаю?

Спасибо за помощь!

1 Ответ

0 голосов
/ 09 мая 2020

Мне удалось исправить эту конкретную проблему, и переходы полностью работают на моих устройствах KitKat.

Когда я тестировал приложение на устройстве Android 10 (Q), я наткнулся на это проблема , когда переходы не работают, но sh приложение не повреждает. Глядя на журналы, можно увидеть, что отражение метода от / с Ghost View API не удалось бы, потому что Android 10 накладывает ограничения на logi c отражений.

Моя проблема также связана с этим Ghost View API.

Решение , предоставленное разработчиком, работающим над этот API должен был обновиться до более свежей и стабильной версии AndroidX Transition API, в которой была устранена эта конкретная проблема.

На момент написания этого ответа самой стабильной версией была 1.3.1.

Исправлены обе проблемы. Вопрос решен.

Мне очень повезло, что я наткнулся на эту проблему, какое решение решило бы мою проблему!

...