Bradleycorn
03/18/2022, 3:22 PMAndroidViewBinding
Composable to inflate a FragmentContainerView
with a Fragment and show it within composable “screen”.
So far though, it seems like I have to create a wrapper xml layout resource with a FragmentContainerView
for every fragment. I was hoping to find a way to just define a single xml layout resource (compose_fragment_container.xml) and write a composable that uses it with AndroidViewBinding
to load an arbitrary Fragment. But so far no luck. Anyone know a way to do this? My current (not working) code in the 🧵Bradleycorn
03/18/2022, 3:27 PM<?xml version="1.0" encoding="utf-8"?>
<androidx.fragment.app.FragmentContainerView
xmlns:android="<http://schemas.android.com/apk/res/android>"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/compose_fragment" />
A Composable to wrap AndroidViewBinding
, inflate the above layout, and add a Fragment
to it:
@Composable
fun MyFragmentBinding(fragment: Class<out Fragment>, fragmentArgs: Bundle? = null) {
val activity = (LocalContext.current as? FragmentActivity)
AndroidViewBinding(factory = { inflater, parent, attachToParent ->
// Inflate the fragment container view
val view = FragmentComposeContainerBinding.inflate(inflater, parent, attachToParent)
val fm = activity?.supportFragmentManager ?: throw IllegalStateException("MyFragmentBinding composable can only be used in a FragmentActivity. Cannot inflate $fragment.")
// Add the fragment to the container view
fm.commit {
setReorderingAllowed(true)
add(R.id.compose_fragment, fragment, fragmentArgs)
}
view
})
}
This works the first time I call it, and loads a fragment just fine. When I call it again though (say when the user navigates to another screen), I end up with a blank screen.Lokesh
03/18/2022, 4:42 PMandroidx.fragment.app.FragmentContainerView
and I use the following block in each of my Fragment's onCreateView
method.
return ComposeView(requireContext()).apply {
setContent {
//MaterialTheme() composable here
}
}
I don't have xml resource for any fragments but I use AndroidX nav components so I just have to define all the fragments in XML nav graph.Bradleycorn
03/18/2022, 6:20 PMclass MyActivity(): FragmentActivity {
private val viewModel: MyActivityViewMmodel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
setContent {
when (viewModel.someState) {
screen1 -> MyFragmentBinding(Screen1Fragment::class.java)
screen2 -> MyFragmentBinding(Screen3Fragment::class.java)
screen3 -> MyFragmentBinding(Screen3Fragment::class.java)
}
}
}
I’m using the Navigation component, so it’s more like this:
class MyActivity(): FragmentActivity {
private val viewModel: MyActivityViewMmodel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
setContent {
val navController = rememberNavController()
NavHost(navController = navController, startDestination = "home") {
composable(route="home") {
MyFragmentBinding(Screen1Fragment::class.java)
}
composable(route="screen2") {
MyFragmentBinding(Screen2Fragment::class.java)
}
composable(route="screen3") {
MyFragmentBinding(Screen3Fragment::class.java)
}
}
}
Bradleycorn
03/18/2022, 6:24 PMnavController.navigate("screen2")
… I get a blank screen.myanmarking
03/18/2022, 7:03 PMBradleycorn
03/18/2022, 7:55 PMCharlie Brown
06/09/2023, 7:46 AMUser Logged In
and Guest
page. Do you have any update on this ?Bradleycorn
06/09/2023, 12:22 PMCharlie Brown
06/12/2023, 2:32 AMlegacy fragment
◦ Put legacy fragment inside FragmentContainerView
xml
◦ Using AndroidViewBinding
to load xml
◦ Inside legacy fragment
add logic to switching Guest/User Logged base on state