Navigation Compose API 可讓您在 Compose 應用程式中瀏覽不同可組合項,同時運用 Jetpack Navigation 的元件、基礎架構和功能。
本頁面說明如何從以片段為基礎的 Jetpack Navigation 遷移至 Navigation Compose,這是以檢視區塊為基礎的 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
的可組合項都能存取的位置設定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
目前,您無法在程式碼中仍使用片段做為目的地時,使用 Navigation Compose。如要開始使用 Navigation Compose,所有目的地都必須是可組合函式。您可以在 Issue Tracker 上追蹤這項功能要求。
轉場動畫
從 Navigation 2.7.0-alpha01 開始,系統直接在 NavHost
中支援設定自訂轉場效果,先前則是在 AnimatedNavHost
中支援。詳情請參閱版本資訊。
瞭解詳情
如要進一步瞭解如何遷移至 Navigation Compose,請參閱下列資源:
- Navigation Compose 程式碼研究室:透過實作程式碼研究室,瞭解 Navigation Compose 的基本概念。
- Now in Android 存放區:這款功能齊全的 Android 應用程式完全以 Kotlin 和 Jetpack Compose 建構而成,遵循 Android 設計和開發最佳做法,並包含 Navigation Compose。
- 將 Sunflower 遷移至 Jetpack Compose:這篇網誌文章記錄了 Sunflower 範例應用程式從 Views 遷移至 Compose 的過程,包括遷移至 Navigation Compose。
- 適用於各種螢幕的 Jetnews:這篇網誌文章記錄了 Jetnews 範例的重構和遷移作業,說明如何使用 Jetpack Compose 和 Navigation Compose 支援所有螢幕。
為您推薦
- 注意:系統會在 JavaScript 關閉時顯示連結文字
- 使用 Compose 進行導覽
- Compose 和其他程式庫
- 其他考量