Navigation Compose API 可讓您在 Compose 應用程式中瀏覽不同可組合項,同時運用 Jetpack Navigation 的元件、基礎架構和功能。
本頁面說明如何從以 Fragment 為基礎的 Jetpack Navigation 遷移至 Navigation Compose,這是將以 View 為基礎的 UI 遷移至 Jetpack Compose 的一部分。
遷移作業必備條件
只要您能夠將所有 Fragment 替換為對應的畫面可組合項,就可以遷移至 Navigation Compose。螢幕可組合項可包含Compose 和 View 內容的混合,但所有導覽目的地都必須是可組合項,才能啟用 Navigation Compose 遷移功能。在此之前,您應繼續在互通 View 和 Compose 程式碼集中使用以片段為基礎的 Navigation 元件。詳情請參閱導覽介面互通說明文件。
在僅限 Compose 的應用程式中使用 Navigation Compose 並非必要條件。只要您保留用於代管可組合內容的片段,即可繼續使用 以片段為基礎的 Navigation 元件。
遷移步驟
無論您採用建議的遷移策略或其他方法,都會達到一個階段,所有導覽目的地都是螢幕可組合項,而片段只會充當可組合項容器。在此階段,您可以遷移至 Navigation Compose。
如果您的應用程式已遵循 UDF 設計模式和我們的架構指南,則除了 UI 層之外,遷移至 Jetpack Compose 和 Navigation Compose 不應需要對應用程式的其他層進行重大重構。
如要遷移至 Navigation Compose,請按照下列步驟操作:
- 在應用程式中加入 Navigation Compose 依附元件。
建立
App-level
可組合函式,並將其新增至Activity
做為 Compose 進入點,取代 View 版面配置的設定:class SampleActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // setContentView<ActivitySampleBinding>(this, R.layout.activity_sample) setContent { SampleApp(/* ... */) } } }
為每個導覽目的地建立類型。針對不需要任何資料的目的地使用
data object
,針對需要資料的目的地使用data class
或class
。@Serializable data object First @Serializable data class Second(val id: String) @Serializable data object Third
請在所有需要參照其的可組合項都能存取的位置設定
NavController
(通常位於App
可組合項內)。這種做法符合狀態升降的原則,讓您能使用NavController
做為可組合畫面之間導覽和維護返回堆疊的可靠資料來源:@Composable fun SampleApp() { val navController = rememberNavController() // ... }
在
App
可組合函式內建立應用程式的NavHost
,並傳遞navController
:@Composable fun SampleApp() { val navController = rememberNavController() SampleNavHost(navController = navController) } @Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { // ... } }
新增
composable
目的地來建構導覽圖。如果每個畫面先前已遷移至 Compose,這個步驟只需將這些畫面可組合項從片段擷取至composable
目的地即可:class FirstFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { return ComposeView(requireContext()).apply { setContent { // FirstScreen(...) EXTRACT FROM HERE } } } } @Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { composable<First> { FirstScreen(/* ... */) // EXTRACT TO HERE } composable<Second> { SecondScreen(/* ... */) } // ... } }
如果您按照設計 Compose UI 的說明操作,特別是如何將
ViewModel
和導覽事件傳遞至可組合項,下一個步驟就是變更向每個螢幕可組合項提供ViewModel
的方式。您通常可以透過hiltViewModel
,使用 Hilt 插入作業及其與 Compose 和 Navigation 的整合點:@Composable fun FirstScreen( // viewModel: FirstViewModel = viewModel(), viewModel: FirstViewModel = hiltViewModel(), onButtonClick: () -> Unit = {}, ) { // ... }
將所有
findNavController()
導覽呼叫替換為navController
呼叫,並將這些呼叫做為導覽事件傳遞至每個可組合畫面,而不是傳遞整個navController
。這種做法遵循最佳做法,將可組合函式中的事件公開給呼叫端,並將navController
維持為單一可靠資料來源。您可以建立為該目的地定義的路徑類別例項,將資料傳遞至目的地。接著,您可以直接從目的地的返回堆疊項目,或使用
SavedStateHandle.toRoute()
從ViewModel
取得該值。@Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { composable<First> { FirstScreen( onButtonClick = { // findNavController().navigate(firstScreenToSecondScreenAction) navController.navigate(Second(id = "ABC")) } ) } composable<Second> { backStackEntry -> val secondRoute = backStackEntry.toRoute<Second>() SecondScreen( id = secondRoute.id, onIconClick = { // findNavController().navigate(secondScreenToThirdScreenAction) navController.navigate(Third) } ) } // ... } }
移除所有 Fragment、相關 XML 版面配置、不必要的導覽和其他資源,以及過時的 Fragment 和 Jetpack Navigation 依附元件。
您可以在設定說明文件中找到相同的步驟,並進一步瞭解 Navigation Compose 相關詳細資料。
常見用途
無論您使用哪個 Navigation 元件,都必須套用相同的導覽原則。
遷移時的常見用途包括:
如要進一步瞭解這些用途,請參閱「使用 Compose 瀏覽」一文。
瀏覽時擷取複雜資料
強烈建議您在瀏覽時不要傳遞複雜的資料物件。而是在執行導覽動作時,將最少必要資訊 (例如專屬 ID 或其他形式的 ID) 做為引數傳遞。應採用單一真實資訊來源 (例如 資料層) 的形式儲存複雜物件。詳情請參閱「瀏覽時擷取複雜資料」。
如果片段會將複雜物件做為引數傳遞,請先考慮重構程式碼,以便從資料層儲存及擷取這些物件。如需範例,請參閱 Now in Android 存放區。
限制
本節將說明 Navigation Compose 目前的限制。
逐步遷移至 Navigation Compose
目前,您無法在程式碼中使用 Fragment 做為目的地,同時使用 Navigation Compose。如要開始使用 Navigation Compose,所有目的地都必須是可組合項。你可以在Issue Tracker 上追蹤這項功能要求。
轉場動畫
從 Navigation 2.7.0-alpha01 開始,AnimatedNavHost
先前支援的設定自訂轉場效果功能,現在也直接支援 NavHost
。詳情請參閱版本資訊。
瞭解詳情
如要進一步瞭解如何遷移至 Navigation Compose,請參閱下列資源:
- Navigation Compose 程式碼研究室:透過實作程式碼研究室,瞭解 Navigation Compose 的基本概念。
- Now in Android 存放區:這是一款功能完整的 Android 應用程式,完全採用 Kotlin 和 Jetpack Compose 建構,遵循 Android 設計和開發最佳做法,並包含 Navigation Compose。
- 將 Sunflower 遷移至 Jetpack Compose:這篇網誌文章記錄了 Sunflower 範例應用程式從 View 遷移至 Compose 的過程,其中也包含遷移至 Navigation Compose 的步驟。
- 適用於各種螢幕的 Jetnews:這篇部落格文章記錄了 Jetpack Compose 和 Navigation Compose 如何支援所有螢幕,並記錄了 Jetnews 範例的改造和遷移作業。
為您推薦
- 注意:系統會在 JavaScript 關閉時顯示連結文字
- 使用 Compose 進行導覽
- Compose 和其他程式庫
- 其他考量