Trình đơn

Trình đơn thả xuống cho phép người dùng nhấp vào biểu tượng, trường văn bản hoặc thành phần khác, sau đó chọn trong danh sách các lựa chọn trên một giao diện tạm thời. Hướng dẫn này mô tả cách tạo cả trình đơn cơ bản và trình đơn phức tạp hơn có đường phân chia và biểu tượng.

Một trình đơn thả xuống có hai lựa chọn sẽ xuất hiện. Biểu tượng có ba dấu chấm dọc cho biết rằng khi nhấp vào biểu tượng này, trình đơn sẽ mở ra.
Hình 1. Một trình đơn thả xuống cơ bản có hai mục.

Nền tảng API

Sử dụng các thành phần DropdownMenu, DropdownMenuItem và IconButton để triển khai trình đơn thả xuống tuỳ chỉnh. Các thành phần DropdownMenu và DropdownMenuItem được dùng để hiển thị các mục trong trình đơn, còn IconButton là trình kích hoạt để hiển thị hoặc ẩn trình đơn thả xuống.

Các tham số chính cho thành phần DropdownMenu bao gồm:

  • expanded: Cho biết liệu trình đơn có hiển thị hay không.
  • onDismissRequest: Dùng để xử lý việc đóng trình đơn.
  • content: Nội dung có thể kết hợp của trình đơn, thường chứa các thành phần kết hợp DropdownMenuItem.

Các tham số chính cho DropdownMenuItem bao gồm:

  • text: Xác định nội dung hiển thị trong mục trình đơn.
  • onClick: Lệnh gọi lại để xử lý hoạt động tương tác với mục trong trình đơn.

Tạo trình đơn thả xuống cơ bản

Đoạn mã sau đây minh hoạ cách triển khai DropdownMenu tối thiểu:

@Composable
fun MinimalDropdownMenu() {
    var expanded by remember { mutableStateOf(false) }
    Box(
        modifier = Modifier
            .padding(16.dp)
    ) {
        IconButton(onClick = { expanded = !expanded }) {
            Icon(Icons.Default.MoreVert, contentDescription = "More options")
        }
        DropdownMenu(
            expanded = expanded,
            onDismissRequest = { expanded = false }
        ) {
            DropdownMenuItem(
                text = { Text("Option 1") },
                onClick = { /* Do something... */ }
            )
            DropdownMenuItem(
                text = { Text("Option 2") },
                onClick = { /* Do something... */ }
            )
        }
    }
}

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

  • Xác định một DropdownMenu cơ bản chứa hai mục trong trình đơn.
  • Tham số expanded kiểm soát chế độ hiển thị của trình đơn ở trạng thái mở rộng hoặc thu gọn.
  • Tham số onDismissRequest xác định một lệnh gọi lại thực thi khi người dùng đóng trình đơn.
  • Thành phần kết hợp DropdownMenuItem đại diện cho các mục có thể chọn trong trình đơn thả xuống.
  • IconButton kích hoạt thao tác mở rộng và thu gọn trình đơn.

Kết quả

Trình đơn thả xuống được kích hoạt bằng biểu tượng có ba dấu chấm dọc. Trình đơn này hiển thị hai lựa chọn, Lựa chọn 1 và Lựa chọn 2.
Hình 2. Trình đơn thả xuống tối giản chỉ có hai lựa chọn.

Tạo trình đơn thả xuống dài hơn

Theo mặc định, DropdownMenu có thể cuộn được nếu không thể hiển thị tất cả các mục trong trình đơn cùng một lúc. Đoạn mã sau đây tạo một trình đơn thả xuống dài hơn, có thể cuộn:

@Composable
fun LongBasicDropdownMenu() {
    var expanded by remember { mutableStateOf(false) }
    // Placeholder list of 100 strings for demonstration
    val menuItemData = List(100) { "Option ${it + 1}" }

    Box(
        modifier = Modifier
            .padding(16.dp)
    ) {
        IconButton(onClick = { expanded = !expanded }) {
            Icon(Icons.Default.MoreVert, contentDescription = "More options")
        }
        DropdownMenu(
            expanded = expanded,
            onDismissRequest = { expanded = false }
        ) {
            menuItemData.forEach { option ->
                DropdownMenuItem(
                    text = { Text(option) },
                    onClick = { /* Do something... */ }
                )
            }
        }
    }
}

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

  • DropdownMenu có thể cuộn được khi tổng chiều cao của nội dung vượt quá không gian có sẵn. Mã này tạo một DropdownMenu có thể cuộn, hiển thị 100 mục phần giữ chỗ.
  • Vòng lặp forEach tạo động các thành phần kết hợp DropdownMenuItem. Các mục không được tạo từng phần, tức là tất cả 100 mục thả xuống đều được tạo và tồn tại trong thành phần.
  • IconButton kích hoạt việc mở rộng và thu gọn DropdownMenu khi được nhấp vào.
  • Hàm lambda onClick trong mỗi DropdownMenuItem cho phép bạn xác định hành động được thực hiện khi người dùng chọn một mục trong trình đơn.

Kết quả

Đoạn mã trước đó tạo ra trình đơn có thể cuộn sau:

Trình đơn thả xuống có nhiều lựa chọn, yêu cầu người dùng phải di chuyển để xem tất cả các mục.
Hình 3. Trình đơn thả xuống dài, có thể cuộn.

Tạo trình đơn thả xuống dài hơn có đường phân chia

Đoạn mã sau đây cho thấy cách triển khai nâng cao hơn của trình đơn thả xuống. Trong đoạn mã này, các biểu tượng ở đầu và cuối được thêm vào các mục trong trình đơn và các đường phân chia sẽ phân tách các nhóm mục trong trình đơn.

@Composable
fun DropdownMenuWithDetails() {
    var expanded by remember { mutableStateOf(false) }

    Box(
        modifier = Modifier
            .fillMaxWidth()
            .padding(16.dp)
    ) {
        IconButton(onClick = { expanded = !expanded }) {
            Icon(Icons.Default.MoreVert, contentDescription = "More options")
        }
        DropdownMenu(
            expanded = expanded,
            onDismissRequest = { expanded = false }
        ) {
            // First section
            DropdownMenuItem(
                text = { Text("Profile") },
                leadingIcon = { Icon(Icons.Outlined.Person, contentDescription = null) },
                onClick = { /* Do something... */ }
            )
            DropdownMenuItem(
                text = { Text("Settings") },
                leadingIcon = { Icon(Icons.Outlined.Settings, contentDescription = null) },
                onClick = { /* Do something... */ }
            )

            HorizontalDivider()

            // Second section
            DropdownMenuItem(
                text = { Text("Send Feedback") },
                leadingIcon = { Icon(Icons.Outlined.Feedback, contentDescription = null) },
                trailingIcon = { Icon(Icons.AutoMirrored.Outlined.Send, contentDescription = null) },
                onClick = { /* Do something... */ }
            )

            HorizontalDivider()

            // Third section
            DropdownMenuItem(
                text = { Text("About") },
                leadingIcon = { Icon(Icons.Outlined.Info, contentDescription = null) },
                onClick = { /* Do something... */ }
            )
            DropdownMenuItem(
                text = { Text("Help") },
                leadingIcon = { Icon(Icons.AutoMirrored.Outlined.Help, contentDescription = null) },
                trailingIcon = { Icon(Icons.AutoMirrored.Outlined.OpenInNew, contentDescription = null) },
                onClick = { /* Do something... */ }
            )
        }
    }
}

Mã này xác định một DropdownMenu trong Box.

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

  • Tham số leadingIcon và trailingIcon thêm biểu tượng vào đầu và cuối DropdownMenuItem.
  • IconButton kích hoạt việc mở rộng trình đơn.
  • DropdownMenu chứa một số thành phần kết hợp DropdownMenuItem, mỗi thành phần đại diện cho một hành động có thể chọn.
  • Thành phần kết hợp HorizontalDivider chèn một đường ngang để phân tách các nhóm mục trong trình đơn.

Kết quả

Đoạn mã trước tạo ra một trình đơn thả xuống có biểu tượng và đường phân chia:

Một trình đơn thả xuống có các mục Hồ sơ, Cài đặt, Gửi ý kiến phản hồi, Giới thiệu và Trợ giúp. Mỗi lựa chọn đều có một biểu tượng, chẳng hạn như biểu tượng hình người cho Hồ sơ.
Hình 4. Trình đơn thả xuống được chia thành các phần có biểu tượng ở đầu và cuối.

Tài nguyên khác