3

I'm trying to inflate a view that contains FragmentContainerView inside a fragment that's being put into a layout.

  • RootView
    • Fragment
      • CustomView
        • FragmentContainerView

Like this:

val transaction = fragmentManager.beginTransaction()
transaction.replace(R.id.main_content, Frag(), "tag");
transaction.commitNowAllowingStateLoss()

where Frag creates a view that inflates a xml like this one:

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:parentTag="android.widget.FrameLayout">

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/nav_graph" />
</merge>

But when I execute the code, my app crashes:

Caused by: java.lang.IllegalStateException: FragmentManager is already executing transactions


How can I avoid this error while using FragmentContainerView (obs.: if I use <fragment> instead of <androidx.fragment.app.FragmentContainerView>, everything works fine)

Augusto Carmo
  • 4,386
  • 2
  • 28
  • 61

1 Answers1

5

You should always, always use childFragmentManager when nesting fragments - the childFragmentManager is never executing transactions when its parent is going through lifecycle changes (which I assume is when you're calling your transaction).

This is actually silently causing issues for you when you use the <fragment> tag as those lifecycle events don't actually occur as a transaction, but directly as part of inflation. Using the wrong FragmentManager means that the fragment and its views will not properly save and restore their state.

The reason it fails with FragmentContainerView is that FragmentContainerView actually does the same FragmentTransaction as you'd do normally.

ianhanniballake
  • 191,609
  • 30
  • 470
  • 443
  • Hi, @ianhanniballake. Thanks for the reply. I'll try to do that by adding the nested `nav_graph` fragment manually. Cheers \o/ (P.S.: a problem I was having with `` when swapping between fragments was probably due to what you've pointed out [silently causing issues]. Thanks for the info) – Augusto Carmo Jul 29 '20 at 11:58