Search code examples
androidkotlinandroid-fragmentsandroid-jetpack-compose

Displaying Fragment in Jetpack Compose using AndroidFragment<>


I have a dependency on 3rd party package which isn't implemented in Jetpack Compose therefore attempting to display Fragment using Android's suggested approach of using AndroidFragment<> but unable to do so, as I keep getting the following exception, not sure what I am doing wrong

java.lang.IllegalStateException: View androidx.compose.ui.platform.AndroidComposeView{896ffd7 VFED..... ......ID 0,0-1440,3120} is not within a subclass of FragmentActivity.

Since, before importing the library we wanted to experiment the approach, we are trying to have the Fragment added to a test application, following is the file and dependency included.

fragment_test.xml

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="@color/purple_500"
    >

    <TextView
        android:id="@+id/tvOne"
        android:text="One Fragment"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="@color/white"
        android:textSize="25sp"
        />

</androidx.constraintlayout.widget.ConstraintLayout>

TestFragment.kt

class TestFragment : Fragment() {
    private lateinit var binding: FragmentTestBinding
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        binding = FragmentTestBinding.inflate(inflater)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        binding.tvOne.setOnClickListener {
            Toast.makeText(context, "Button Has Been Clicked! Yipeee!!!!", Toast.LENGTH_LONG)
        }
    }
}

MainActivity.kt

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)



        enableEdgeToEdge()
        setContent {
            DriveTestAceTheme {
                Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
                    Greeting(
                        name = "Android",
                        modifier = Modifier.padding(innerPadding)
                    )
                }
            }
        }
    }
    @Composable
    fun Greeting(name: String, modifier: Modifier = Modifier) {
        AndroidFragment<TestFragment>(
            modifier = Modifier.fillMaxSize()
        )
    }
}

build.gradle.kts

    // Fragment Compose dependencies
    val fragment_version = "1.8.3"
    implementation("androidx.fragment:fragment:$fragment_version")
    implementation("androidx.fragment:fragment-ktx:$fragment_version")
    implementation("androidx.fragment:fragment-compose:$fragment_version")
    debugImplementation("androidx.fragment:fragment-testing:$fragment_version")

I tried using the AndroidFragment<> as that seems to be the suggested approach by Android community but not getting anywhere, attempted to replicate the things others have done but still not getting any luck. Seems like I am missing something.


Solution

  • The exception is quite clear here, you are using AndroidFragment composable in a compose view inside of MainActivity which is a subclass of ComponentActivity. ComponentActivity can't handle fragments, there is a FragmentActivity for that. You should make your MainActivity extend the FragmentActivity.