Tạo ảnh động giữa các đích đến

NavDisplay cung cấp các tính năng ảnh động tích hợp để tạo hiệu ứng chuyển đổi hình ảnh mượt mà khi người dùng di chuyển trong ứng dụng. Bạn có thể tuỳ chỉnh các ảnh động này trên toàn cục cho NavDisplay hoặc trên cơ sở mỗi NavEntry bằng cách sử dụng siêu dữ liệu.

Ghi đè hiệu ứng chuyển đổi mặc định

NavDisplay sử dụng ContentTransform để xác định cách nội dung tạo ảnh động trong quá trình điều hướng. Bạn có thể ghi đè hành vi ảnh động mặc định bằng cách cung cấp tham số chuyển đổi cho NavDisplay.

  • transitionSpec: Tham số này xác định ContentTransform để áp dụng khi nội dung được thêm vào ngăn xếp lui (tức là khi di chuyển về phía trước).
  • popTransitionSpec: Tham số này xác định ContentTransform để áp dụng khi nội dung bị xoá khỏi ngăn xếp lui (tức là khi điều hướng lui).
  • predictivePopTransitionSpec: Tham số này xác định ContentTransform để áp dụng khi nội dung được bật lên bằng cử chỉ vuốt ngược để dự đoán.

Ghi đè hiệu ứng chuyển đổi ở cấp NavEntry riêng lẻ

Bạn cũng có thể xác định ảnh động tuỳ chỉnh cho các NavEntry cụ thể bằng cách sử dụng siêu dữ liệu của chúng. NavDisplay nhận dạng các khoá siêu dữ liệu đặc biệt để áp dụng chuyển đổi cho mỗi mục nhập:

  • NavDisplay.transitionSpec: Sử dụng hàm trợ giúp này để xác định ảnh động điều hướng chuyển tiếp.
  • NavDisplay.popTransitionSpec: Sử dụng hàm trợ giúp này để xác định ảnh động điều hướng lui cho một NavEntry cụ thể.
  • NavDisplay.predictivePopTransitionSpec: Sử dụng hàm trợ giúp này để xác định ảnh động cho cử chỉ xem trước thao tác quay lại cho một NavEntry cụ thể.

Các chuyển đổi siêu dữ liệu trên mỗi mục này sẽ ghi đè các chuyển đổi toàn cục cùng tên của NavDisplay.

Đoạn mã sau đây minh hoạ cả hiệu ứng chuyển đổi NavDisplay chung và một hiệu ứng ghi đè ở cấp NavEntry riêng lẻ:

@Serializable
data object ScreenA : NavKey

@Serializable
data object ScreenB : NavKey

@Serializable
data object ScreenC : NavKey

class AnimatedNavDisplayActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {

            Scaffold { paddingValues ->

                val backStack = rememberNavBackStack(ScreenA)

                NavDisplay(
                    backStack = backStack,
                    onBack = { backStack.removeLastOrNull() },
                    entryProvider = entryProvider {
                        entry<ScreenA> {
                            ContentOrange("This is Screen A") {
                                Button(onClick = { backStack.add(ScreenB) }) {
                                    Text("Go to Screen B")
                                }
                            }
                        }
                        entry<ScreenB> {
                            ContentMauve("This is Screen B") {
                                Button(onClick = { backStack.add(ScreenC) }) {
                                    Text("Go to Screen C")
                                }
                            }
                        }
                        entry<ScreenC>(
                            metadata = NavDisplay.transitionSpec {
                                // Slide new content up, keeping the old content in place underneath
                                slideInVertically(
                                    initialOffsetY = { it },
                                    animationSpec = tween(1000)
                                ) togetherWith ExitTransition.KeepUntilTransitionsFinished
                            } + NavDisplay.popTransitionSpec {
                                // Slide old content down, revealing the new content in place underneath
                                EnterTransition.None togetherWith
                                    slideOutVertically(
                                        targetOffsetY = { it },
                                        animationSpec = tween(1000)
                                    )
                            } + NavDisplay.predictivePopTransitionSpec {
                                // Slide old content down, revealing the new content in place underneath
                                EnterTransition.None togetherWith
                                    slideOutVertically(
                                        targetOffsetY = { it },
                                        animationSpec = tween(1000)
                                    )
                            }
                        ) {
                            ContentGreen("This is Screen C")
                        }
                    },
                    transitionSpec = {
                        // Slide in from right when navigating forward
                        slideInHorizontally(initialOffsetX = { it }) togetherWith
                            slideOutHorizontally(targetOffsetX = { -it })
                    },
                    popTransitionSpec = {
                        // Slide in from left when navigating back
                        slideInHorizontally(initialOffsetX = { -it }) togetherWith
                            slideOutHorizontally(targetOffsetX = { it })
                    },
                    predictivePopTransitionSpec = {
                        // Slide in from left when navigating back
                        slideInHorizontally(initialOffsetX = { -it }) togetherWith
                            slideOutHorizontally(targetOffsetX = { it })
                    },
                    modifier = Modifier.padding(paddingValues)
                )
            }
        }
    }
}

Hình 1. Ứng dụng có ảnh động tuỳ chỉnh.