Di chuyển Jetpack Navigation sang Navigation Compose

Navigation Compose API (API Điều hướng Compose) cho phép bạn di chuyển giữa các thành phần kết hợp trong Ứng dụng Compose, đồng thời tận dụng thành phần Điều hướng của Jetpack, cơ sở hạ tầng và các tính năng.

Trang này mô tả cách di chuyển từ thành phần Điều hướng Jetpack dựa trên mảnh sang Navigation Compose, trong quá trình di chuyển giao diện người dùng lớn hơn dựa trên Khung hiển thị sang Jetpack Soạn thư.

Điều kiện tiên quyết để di chuyển

Bạn có thể di chuyển sang Navigation Compose sau khi có thể thay thế tất cả Các mảnh có thành phần kết hợp màn hình tương ứng. Các thành phần kết hợp màn hình có thể chứa kết hợp nội dung trong Compose và Khung hiển thị, nhưng tất cả đích điều hướng đều phải thành phần kết hợp để cho phép di chuyển Navigation Compose. Cho đến lúc đó, bạn nên tiếp tục sử dụng Thành phần điều hướng dựa trên mảnh trong Khung hiển thị và Cơ sở mã của Compose. Xem tài liệu về khả năng tương tác điều hướng để biết thêm thông tin của bạn.

Việc sử dụng Navigation Compose trong ứng dụng chỉ dành cho Compose không phải là điều kiện tiên quyết. Bạn có thể tiếp tục sử dụng Thành phần điều hướng dựa trên mảnh, miễn là bạn duy trì Các mảnh để lưu trữ nội dung thành phần kết hợp.

Các bước di chuyển

Bạn đang tuân theo chiến lược di chuyển đề xuất của chúng tôi hay đang thực hiện một phương pháp khác, bạn sẽ đạt đến một điểm mà tất cả các đích điều hướng thành phần kết hợp màn hình, trong đó các Mảnh chỉ đóng vai trò là vùng chứa thành phần kết hợp. Lúc này , bạn có thể di chuyển sang Navigation Compose.

Nếu ứng dụng của bạn đã tuân thủ mẫu thiết kế UDFhướng dẫn của chúng tôi để cấu trúc, thì việc di chuyển sang Jetpack Compose và Navigation Compose yêu cầu tái cấu trúc chính các lớp khác trong ứng dụng, ngoài lớp giao diện người dùng.

Để di chuyển sang Navigation Compose, hãy làm theo các bước sau:

  1. Thêm phần phụ thuộc Navigation Compose vào ứng dụng.
  2. Tạo một thành phần kết hợp App-level rồi thêm thành phần đó vào Activity dưới dạng Điểm truy cập Compose, thay thế thông tin thiết lập của bố cục Thành phần hiển thị:

    class SampleActivity : ComponentActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            // setContentView<ActivitySampleBinding>(this, R.layout.activity_sample)
            setContent {
                SampleApp(/* ... */)
            }
        }
    }

  3. Tạo các loại cho từng đích đến điều hướng. Sử dụng data object cho đích không yêu cầu bất kỳ dữ liệu nào và data class hoặc class cho đích đến yêu cầu dữ liệu.

    @Serializable data object First
    @Serializable data class Second(val id: String)
    @Serializable data object Third
    

  4. Thiết lập NavController ở một nơi mà tất cả thành phần kết hợp cần để tham chiếu đến việc nó có quyền truy cập vào nó (phần này thường nằm trong App của bạn thành phần kết hợp). Phương pháp này tuân theo các nguyên tắc chuyển trạng thái lên trên và cho phép bạn sử dụng NavController làm nguồn đáng tin cậy cho di chuyển giữa các màn hình có thể kết hợp và duy trì ngăn xếp lui:

    @Composable
    fun SampleApp() {
        val navController = rememberNavController()
        // ...
    }

  5. Tạo NavHost của ứng dụng bên trong thành phần kết hợp App rồi truyền tham số navController:

    @Composable
    fun SampleApp() {
        val navController = rememberNavController()
    
        SampleNavHost(navController = navController)
    }
    
    @Composable
    fun SampleNavHost(
        navController: NavHostController
    ) {
        NavHost(navController = navController, startDestination = First) {
            // ...
        }
    }

  6. Thêm các đích đến composable để tạo biểu đồ điều hướng. Nếu mỗi màn hình của bạn đã được di chuyển trước đó sang Compose, bước này chỉ bao gồm trích xuất các thành phần kết hợp màn hình này từ Mảnh vào composable đích đến:

    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(/* ... */)
            }
            // ...
        }
    }

  7. Nếu bạn làm theo hướng dẫn về thiết kế cấu trúc giao diện người dùng Compose, cụ thể là cách truyền ViewModel và các sự kiện điều hướng đến thành phần kết hợp, bước tiếp theo là thay đổi cách bạn cung cấp ViewModel cho từng thành phần kết hợp màn hình. Thường thì bạn có thể sử dụng tính năng chèn Hilt và chức năng tích hợp điểm bằng Compose và Navigation thông qua hiltViewModel:

    @Composable
    fun FirstScreen(
        // viewModel: FirstViewModel = viewModel(),
        viewModel: FirstViewModel = hiltViewModel(),
        onButtonClick: () -> Unit = {},
    ) {
        // ...
    }

  8. Thay thế tất cả lệnh gọi điều hướng findNavController() bằng navController và truyền chúng dưới dạng sự kiện điều hướng đến từng màn hình có thể kết hợp, thay vì so với việc truyền toàn bộ navController. Phương pháp này tuân thủ phương pháp các phương thức hiển thị sự kiện từ các hàm có khả năng kết hợp cho phương thức gọi và giữ navController làm nguồn đáng tin cậy duy nhất.

    Dữ liệu có thể được truyền đến một đích đến bằng cách tạo một bản sao của tuyến đường. được xác định cho đích đến đó. Sau đó, bạn có thể lấy mã nguồn trực tiếp từ mục ngăn xếp lui tại đích đến hoặc từ ViewModel bằng cách sử dụng SavedStateHandle.toRoute().

    @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)
                    }
                )
            }
            // ...
        }
    }

  9. Xoá tất cả Mảnh, bố cục XML có liên quan, thành phần điều hướng không cần thiết và các lỗi khác cũng như các phần phụ thuộc cũ của Mảnh và Điều hướng Jetpack.

Bạn có thể xem các bước tương tự với nhiều thông tin chi tiết khác liên quan đến thành phần Điều hướng trong Compose trong Tài liệu về cách thiết lập.

Các trường hợp sử dụng phổ biến

Bất kể bạn đang sử dụng thành phần Điều hướng nào, các nguyên tắc giống nhau sẽ áp dụng thao tác.

Sau đây là các trường hợp sử dụng phổ biến khi di chuyển:

Để biết thêm thông tin chi tiết về các trường hợp sử dụng này, hãy xem bài viết Điều hướng bằng Compose.

Truy xuất dữ liệu phức tạp khi điều hướng

Bạn không nên chuyển các đối tượng dữ liệu phức tạp khi điều hướng. Thay vào đó, hãy chuyển thông tin cần thiết tối thiểu, chẳng hạn như giá trị nhận dạng duy nhất hoặc dạng mã nhận dạng khác làm đối số khi thực hiện các thao tác điều hướng. Bạn nên lưu trữ các đối tượng phức tạp dưới dạng dữ liệu trong một nguồn đáng tin cậy, chẳng hạn như dữ liệu . Để biết thêm thông tin, hãy xem phần Truy xuất dữ liệu phức tạp khi điều hướng.

Nếu Mảnh của bạn đang truyền các đối tượng phức tạp dưới dạng đối số, hãy cân nhắc việc tái cấu trúc mã của mình trước, theo cách cho phép lưu trữ và tìm nạp các đối tượng này từ lớp dữ liệu. Xem kho lưu trữ Now in Android để biết ví dụ.

Các điểm hạn chế

Phần này mô tả các hạn chế hiện tại của Navigation Compose.

Di chuyển dần sang Navigation Compose

Hiện tại, bạn không thể sử dụng Navigation Compose trong khi vẫn dùng các Mảnh làm đích trong mã của bạn. Để bắt đầu sử dụng Navigation Compose, tất cả đích đến cần phải là thành phần kết hợp. Bạn có thể theo dõi yêu cầu về tính năng này trên Công cụ theo dõi lỗi.

Ảnh động chuyển tiếp

Bắt đầu với phiên bản Navigation 2.7.0-alpha01, hỗ trợ chế độ cài đặt tuỳ chỉnh hiệu ứng chuyển đổi, trước đây là từ AnimatedNavHost, hiện là được hỗ trợ trực tiếp trong NavHost. Hãy đọc qua ghi chú phát hành cho biết thêm thông tin.

Tìm hiểu thêm

Để biết thêm thông tin về cách di chuyển sang Navigation Compose, hãy xem các nội dung sau tài nguyên:

  • Lớp học lập trình về Navigation Compose: Tìm hiểu kiến thức cơ bản về Navigation Compose thông qua một lớp học lập trình thực hành.
  • Kho lưu trữ Now in Android: Một ứng dụng Android với đầy đủ chức năng được xây dựng hoàn toàn bằng Kotlin và Jetpack Compose, tuân theo thiết kế của Android và các phương pháp phát triển hay nhất, trong đó có cả Navigation Compose.
  • Di chuyển Sunflower sang Jetpack Compose: Một bài đăng trên blog ghi lại hành trình di chuyển của ứng dụng mẫu Sunflower từ Views sang Compose, cũng bao gồm việc di chuyển sang Navigation Compose.
  • Jetnews cho mọi màn hình: Một bài đăng trên blog ghi lại việc tái cấu trúc và di chuyển mẫu Jetnews để hỗ trợ mọi màn hình có Jetpack Compose và Navigation Compose.