Ngăn điều hướng

Thành phần ngăn điều hướng là một trình đơn trượt vào, cho phép người dùng di chuyển đến nhiều phần trong ứng dụng. Người dùng có thể kích hoạt thành phần này bằng cách vuốt từ bên cạnh hoặc nhấn vào biểu tượng trình đơn.

Hãy xem xét ba trường hợp sử dụng sau đây để triển khai Ngăn điều hướng:

  • Sắp xếp nội dung: Cho phép người dùng chuyển đổi giữa các danh mục khác nhau, chẳng hạn như trong ứng dụng tin tức hoặc ứng dụng viết blog.
  • Quản lý tài khoản: Cung cấp đường liên kết nhanh đến phần cài đặt tài khoản và hồ sơ trong các ứng dụng có tài khoản người dùng.
  • Khám phá tính năng: Sắp xếp nhiều tính năng và chế độ cài đặt trong một trình đơn để giúp người dùng dễ dàng khám phá và truy cập trong các ứng dụng phức tạp.

Trong Material Design, có hai loại ngăn điều hướng:

  • Tiêu chuẩn: Chia sẻ không gian trong màn hình với nội dung khác.
  • Phương thức: Xuất hiện ở đầu nội dung khác trong màn hình.
Ví dụ về ngăn điều hướng Material Design 3 ở chế độ sáng và tối.
Hình 1. Ví dụ về ngăn điều hướng.

Ví dụ

Bạn có thể sử dụng composable ModalNavigationDrawer để triển khai ngăn điều hướng.

Sử dụng khe drawerContent để cung cấp ModalDrawerSheet và cung cấp nội dung của ngăn, như trong ví dụ sau:

ModalNavigationDrawer(
    drawerContent = {
        ModalDrawerSheet {
            Text("Drawer title", modifier = Modifier.padding(16.dp))
            HorizontalDivider()
            NavigationDrawerItem(
                label = { Text(text = "Drawer Item") },
                selected = false,
                onClick = { /*TODO*/ }
            )
            // ...other drawer items
        }
    }
) {
    // Screen content
}

ModalNavigationDrawer chấp nhận một số thông số ngăn chứa bổ sung. Ví dụ: bạn có thể chuyển đổi để xem ngăn chứa có phản hồi với các lệnh kéo bằng thông số gesturesEnabled hay không, như trong ví dụ sau:

ModalNavigationDrawer(
    drawerContent = {
        ModalDrawerSheet {
            // Drawer contents
        }
    },
    gesturesEnabled = false
) {
    // Screen content
}

Kiểm soát hành vi

Để kiểm soát cách ngăn điều hướng mở và đóng, hãy sử dụng DrawerState. Bạn nên chuyển DrawerState đến ModalNavigationDrawer bằng tham số drawerState.

DrawerState cung cấp quyền truy cập vào các hàm open và close, cũng như các thuộc tính liên quan đến trạng thái ngăn chứa hiện tại. Các hàm tạm ngưng này cần phải có CoroutineScope mà bạn có thể tạo thực thể bằng cách sử dụng rememberCoroutineScope. Bạn cũng có thể gọi các hàm tạm ngưng để phản hồi các sự kiện giao diện người dùng.

val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
val scope = rememberCoroutineScope()
ModalNavigationDrawer(
    drawerState = drawerState,
    drawerContent = {
        ModalDrawerSheet { /* Drawer content */ }
    },
) {
    Scaffold(
        floatingActionButton = {
            ExtendedFloatingActionButton(
                text = { Text("Show drawer") },
                icon = { Icon(Icons.Filled.Add, contentDescription = "") },
                onClick = {
                    scope.launch {
                        drawerState.apply {
                            if (isClosed) open() else close()
                        }
                    }
                }
            )
        }
    ) { contentPadding ->
        // Screen content
    }
}

Tạo nhóm trong ngăn điều hướng

Đoạn mã sau đây cho biết cách tạo ngăn điều hướng chi tiết, có các phần và đường phân chia:

@Composable
fun DetailedDrawerExample(
    content: @Composable (PaddingValues) -> Unit
) {
    val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
    val scope = rememberCoroutineScope()

    ModalNavigationDrawer(
        drawerContent = {
            ModalDrawerSheet {
                Column(
                    modifier = Modifier.padding(horizontal = 16.dp)
                        .verticalScroll(rememberScrollState())
                ) {
                    Spacer(Modifier.height(12.dp))
                    Text("Drawer Title", modifier = Modifier.padding(16.dp), style = MaterialTheme.typography.titleLarge)
                    HorizontalDivider()

                    Text("Section 1", modifier = Modifier.padding(16.dp), style = MaterialTheme.typography.titleMedium)
                    NavigationDrawerItem(
                        label = { Text("Item 1") },
                        selected = false,
                        onClick = { /* Handle click */ }
                    )
                    NavigationDrawerItem(
                        label = { Text("Item 2") },
                        selected = false,
                        onClick = { /* Handle click */ }
                    )

                    HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp))

                    Text("Section 2", modifier = Modifier.padding(16.dp), style = MaterialTheme.typography.titleMedium)
                    NavigationDrawerItem(
                        label = { Text("Settings") },
                        selected = false,
                        icon = { Icon(Icons.Outlined.Settings, contentDescription = null) },
                        badge = { Text("20") }, // Placeholder
                        onClick = { /* Handle click */ }
                    )
                    NavigationDrawerItem(
                        label = { Text("Help and feedback") },
                        selected = false,
                        icon = { Icon(Icons.AutoMirrored.Outlined.Help, contentDescription = null) },
                        onClick = { /* Handle click */ },
                    )
                    Spacer(Modifier.height(12.dp))
                }
            }
        },
        drawerState = drawerState
    ) {
        Scaffold(
            topBar = {
                TopAppBar(
                    title = { Text("Navigation Drawer Example") },
                    navigationIcon = {
                        IconButton(onClick = {
                            scope.launch {
                                if (drawerState.isClosed) {
                                    drawerState.open()
                                } else {
                                    drawerState.close()
                                }
                            }
                        }) {
                            Icon(Icons.Default.Menu, contentDescription = "Menu")
                        }
                    }
                )
            }
        ) { innerPadding ->
            content(innerPadding)
        }
    }
}

Các điểm chính về mã

  • Điền sẵn drawerContent bằng Column chứa các mục, đường phân chia và mục điều hướng.
  • ModalDrawerSheet cung cấp kiểu Material Design cho ngăn.
  • HorizontalDivider phân tách các phần trong ngăn kéo.
  • ModalNavigationDrawer tạo ngăn điều hướng.
  • drawerContent xác định nội dung của ngăn kéo.
  • Bên trong ModalDrawerSheet, Column sắp xếp các phần tử ngăn kéo theo chiều dọc.
  • Thành phần kết hợp NavigationDrawerItem đại diện cho từng mục trong ngăn điều hướng.
  • Scaffold cung cấp cấu trúc cơ bản của màn hình, bao gồm cả TopAppBar.
  • navigationIcon trong TopAppBar kiểm soát trạng thái mở và đóng của ngăn.

Kết quả

Hình ảnh sau đây cho thấy giao diện của ngăn điều hướng khi mở, với các mục và phần được hiển thị:

Ngăn điều hướng chi tiết có hai phần, mỗi phần có nhiều mục và biểu tượng được gắn nhãn.
Hình 2. Một ngăn điều hướng mở ra với hai nhóm lồng nhau.

Tài nguyên khác