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 和其他程式庫
- 其他考量