I tried to load a Fragment in Compose as below, through the supportFragmentManager
as shown below.
class MainActivity : FragmentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
AndroidViewBinding(FragmentContainerBinding::inflate) {
supportFragmentManager.beginTransaction()
.replace(container.id, MyFragment()).commit()
}
}
}
}
However, when the view is shown, the fragment gets committed (loaded) several times (i.e. the onCreate()
is called several times)
Any way to prevent committing several times? Is there a way to resume the state as well (e.g. in case got killed by the system, how to get it restored)?
(note: I'm not using the androidx.fragment.app.FragmentContainerView
in the XML as in Developer Doc I do have different fragments per some logic (not shown here), hence I'll have to use supportFragmentManager
)
Found a way to get this working
class MainActivity : FragmentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
FragmentContainer(
modifier = Modifier.fillMaxSize(),
fragmentManager = supportFragmentManager,
commit = { add(it, MyFragment()) }
)
}
}
}
@Composable
fun FragmentContainer(
modifier: Modifier = Modifier,
fragmentManager: FragmentManager,
commit: FragmentTransaction.(containerId: Int) -> Unit
) {
val containerId by rememberSaveable { mutableStateOf(View.generateViewId()) }
AndroidView(
modifier = modifier,
factory = { context ->
fragmentManager.findFragmentById(containerId)?.view
?.also { (it.parent as? ViewGroup)?.removeView(it) }
?: FragmentContainerView(context)
.apply { id = containerId }
.also {
fragmentManager.commit { commit(it.id) }
}
}
)
}
Note this will need Fragment's KTX
implementation "androidx.fragment:fragment-ktx:1.4.1"