互通性方案

本食譜示範如何在 Navigation3 應用程式中使用 AndroidFragmentAndroidView

功能

  • AndroidFragment:說明如何在可組合項目的地內嵌入 Fragment。
  • AndroidView:說明如何在可組合項目的地中嵌入傳統 Android View。

重要元件

  • InteropActivity:主活動,用於代管導覽功能。
  • MyCustomFragment:範例中使用的簡單 Fragment。
  • AndroidFragment<T>:可代管片段的可組合函式。
  • AndroidView:可代管 Android View 的可組合函式。

用量

  1. 執行 InteropActivity
  2. 初始畫面會顯示片段。
  3. 按一下「前往檢視畫面」,即可前往顯示 TextView 的畫面。
package com.example.nav3recipes.interop

import android.annotation.SuppressLint
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.fragment.app.Fragment

class MyCustomFragment : Fragment() {
    @SuppressLint("SetTextI18n")
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        return TextView(requireContext()).apply {
            text = "My Fragment"
        }
    }
}
package com.example.nav3recipes.interop

import android.annotation.SuppressLint
import android.os.Bundle
import android.widget.TextView
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.ui.Modifier
import androidx.compose.ui.viewinterop.AndroidView
import androidx.fragment.app.FragmentActivity
import androidx.fragment.compose.AndroidFragment
import androidx.lifecycle.compose.dropUnlessResumed
import androidx.navigation3.runtime.NavKey
import androidx.navigation3.runtime.entryProvider
import androidx.navigation3.runtime.rememberNavBackStack
import androidx.navigation3.ui.NavDisplay
import com.example.nav3recipes.ui.setEdgeToEdgeConfig
import kotlinx.serialization.Serializable

@Serializable
private data object FragmentRoute : NavKey

@Serializable
private data class ViewRoute(val id: String) : NavKey

class InteropActivity : FragmentActivity() {

    @SuppressLint("SetTextI18n")
    override fun onCreate(savedInstanceState: Bundle?) {
        setEdgeToEdgeConfig()
        super.onCreate(savedInstanceState)
        setContent {
            val backStack = rememberNavBackStack(FragmentRoute)

            NavDisplay(
                backStack = backStack,
                onBack = { backStack.removeLastOrNull() },
                entryProvider = entryProvider {
                    entry<FragmentRoute> {
                        Column(Modifier.fillMaxSize().wrapContentSize()) {
                            AndroidFragment<MyCustomFragment>()
                            Button(onClick = dropUnlessResumed {
                                backStack.add(ViewRoute("123"))
                            }) {
                                Text("Go to View")
                            }
                        }
                    }
                    entry<ViewRoute> { key ->
                        AndroidView(
                            modifier = Modifier.fillMaxSize().wrapContentSize(),
                            factory = { context ->
                                TextView(context).apply {
                                    text = "My View with key: ${key.id}"
                                }
                            }
                        )
                    }
                }
            )
        }
    }
}