#android #android-fragments #android-jetpack-compose
Вопрос:
Я играю с compose и попытался включить фрагмент в представление compose AndroidView.
Итак, в моей ситуации у нас есть фрагмент с составным представлением, а внутри составного представления есть представление AndroidView, которое создает фрагментный контент и добавляет фрагмент.
override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { return ComposeView(requireContext()).apply { setContent { AppTheme { GalleryScreen( factory = viewModelFactory, remoteConfig = remoteConfig, id = id, currentPosition = currentPositionState, onBack = { router.back(requireActivity()) }, ) { AndroidView( modifier = Modifier .fillMaxWidth() .wrapContentHeight(), factory = { FragmentContainerView(context).apply { id = R.id.pFIC } }, update = { childFragmentManager.beginTransaction().replace( R.id.pFIC, PIFragment::class.java, buildArguments( id = id, origin = origin, ), null ).commitAllowingStateLoss() }, ) } } } } }
Все работало нормально, но когда мы опубликовали этот код в производстве, мы увидели сбой в firebase:
java.lang.IllegalArgumentException: No view found for id 0x7f0b072b (...:id/pFIC) for fragment PIFragment{ef1f89b} (bdbe15f0-679d-41bb-8a27-367655f73545 id=0x7f0b072b) at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:513) at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282) at androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112) at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1647) at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3128) at androidx.fragment.app.FragmentManager.dispatchViewCreated(FragmentManager.java:3065) at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:2988) at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:546) at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282) at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2180) at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2100) at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:2002) at androidx.fragment.app.FragmentManager$5.run(FragmentManager.java:524) at android.os.Handler.handleCallback(Handler.java:873) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:193) at android.app.ActivityThread.main(ActivityThread.java:6669) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Ответ №1:
На самом деле сбой произошел после того, как родительский фрагмент был воссоздан.
В моем случае из-за навигации:
- Фрагмент (с пифрагментом)
- перейдите к фрагменту
- вернемся к фрагменту
Сбой, потому что менеджер фрагментов пытается воссоздать фрагментацию и фрагментацию, но проход компоновки не выполнен, поэтому pFIC еще не существует.
Решение состояло в том, чтобы удалить фрагмент, когда родительский фрагмент представления будет уничтожен.
override fun onDestroyView() { childFragmentManager.findFragmentById(R.id.pFIC)?.let { fragment -gt; childFragmentManager.beginTransaction().remove(fragment).commitAllowingStateLoss() } super.onDestroyView() }