I'm attempting to add Jetpack Compose composables to my xml file in a fragment.
When I try to run it on a device I'm getting an error:
Cannot add views to ComposeView; only Compose content is supported
Fragment:
class ComposeFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(
R.layout.activity_main, container, false
)
view.findViewById<ComposeView>(R.id.compose_view).setContent {
Column(
modifier = Modifier
.border(border = BorderStroke(1.dp, Color.Black))
.padding(16.dp)
) {
Text("THIS IS A COMPOSABLE INSIDE THE FRAGMENT XML")
Spacer(modifier = Modifier.padding(10.dp))
CircularProgressIndicator()
Spacer(modifier = Modifier.padding(10.dp))
Text("NEAT")
Spacer(modifier = Modifier.padding(10.dp))
}
}
return view
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@ id/main_container"
/>
<androidx.compose.ui.platform.ComposeView
android:id="@ id/compose_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</RelativeLayout>
MainActivity.kt:
open class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
supportFragmentManager.beginTransaction()
.replace(R.id.compose_view, ComposeFragment())
.commit()
}
}
I'm not really sure what this error means or how to address it. I can't find this error anywhere by googling.
CodePudding user response:
In your MainActivity you are trying to put a fragment inside a ComposeView (which takes only Composable).
You should specify the right container for your Fragment:
supportFragmentManager.beginTransaction() .replace(R.id.main_container, ComposeFragment()) .commit()
CodePudding user response:
replace(R.id.compose_view, ComposeFragment())
is adding a Fragment to your ComposeView
, not to your FragmentContainerView
- that's what is adding a View
to your ComposeView
.
If you want to add a Fragment to your FragmentContainerView
, you'll need to use the ID of the FragmentContainerView
:
open class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Always surround any FragmentTransactions in a
// savedInstanceState == null since fragment are
// automatically restored and you don't want to replace
// those restored fragments
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.main_container, ComposeFragment())
.commit()
}
}
}
It isn't clear why your Activity is inflating activity_main
and your Fragment is also inflating activity_main
- those should be different layouts and you should choose if you want your activity's layout to only host a fragment (thereby removing the ComposeView
from its layout) and have the fragment contain your ComposeView
or if you want to skip the fragment entirely and directly have your ComposeView
in your Activity. Doing both (in particular, in your layout where they would overlap one another due to your use of RelativeLayout
) doesn't make much sense.