Lọc danh sách trong khi nhập

Hướng dẫn này giải thích cách lọc danh sách chuỗi dựa trên dữ liệu nhập văn bản trong Jetpack Compose. Sử dụng phương pháp này để tự động cập nhật danh sách dựa trên cụm từ tìm kiếm của người dùng.

Khả năng tương thích của phiên bản

Cách triển khai này hoạt động với Compose phiên bản 1.2.0 trở lên.

Phần phụ thuộc

Thêm các phần phụ thuộc sau vào build.gradle:

Lọc danh sách dựa trên dữ liệu nhập văn bản

Các đoạn mã sau đây cùng nhau tạo ra một danh sách cập nhật theo thời gian thực khi người dùng nhập. Ví dụ này sử dụng ViewModel để lưu trữ dữ liệu danh sách và logic lọc, trong khi hàm FilterTextView() tạo giao diện người dùng tự động cập nhật bất cứ khi nào văn bản bộ lọc thay đổi.

class FilterTextViewModel : ViewModel() {
    private val items = listOf(
        "Cupcake",
        "Donut",
        "Eclair",
        "Froyo",
        "Gingerbread",
        "Honeycomb",
        "Ice Cream Sandwich"
    )

    private val _filteredItems = MutableStateFlow(items)
    var filteredItems: StateFlow<List<String>> = _filteredItems

    fun filterText(input: String) {
        // This filter returns the full items list when input is an empty string.
        _filteredItems.value = items.filter { it.contains(input, ignoreCase = true) }
    }
}

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

  • ViewModel tóm tắt công việc lọc khỏi thành phần kết hợp.
  • ViewModel chứa cả danh sách ban đầu và danh sách đã lọc. Phương thức này xác định một danh sách các mục và MutableStateFlow để lưu giữ các mục đã lọc.
  • Hàm filterText lọc danh sách dựa trên chuỗi đầu vào được cung cấp và cập nhật trạng thái filteredItems. Trạng thái này được truyền trở lại giao diện người dùng.

@Composable
fun FilterTextView(modifier: Modifier = Modifier, viewModel: FilterTextViewModel = viewModel()) {
    val filteredItems by viewModel.filteredItems.collectAsStateWithLifecycle()
    var text by rememberSaveable { mutableStateOf("") }

    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(all = 10.dp)
    ) {
        OutlinedTextField(
            value = text,
            onValueChange = {
                text = it
                viewModel.filterText(text)
            },
            label = { Text("Filter Text") },
            modifier = Modifier.fillMaxWidth()
        )

        LazyColumn {
            items(
                count = filteredItems.size,
                key = { index -> filteredItems[index] }
            ) {
                ListItem(
                    headlineContent = { Text(filteredItems[it]) },
                    modifier = Modifier
                        .fillParentMaxWidth()
                        .padding(10.dp)
                )
            }
        }
    }
}

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

  • Hiển thị OutlinedTextField cho dữ liệu đầu vào của người dùng và LazyColumn để hiển thị các mục danh sách đã lọc.
  • Thu thập luồng trạng thái filteredItems từ ViewModel và chuyển đổi luồng đó thành đối tượng State nhận biết được vòng đời.
    • collectAsStateWithLifecycle thu thập giá trị mới nhất từ StateFlow và kết hợp lại giao diện người dùng khi giá trị thay đổi.
  • text by rememberSaveable { mutableStateOf("") } tạo một biến trạng thái text để lưu giữ văn bản hiện tại đã nhập vào trường văn bản bộ lọc.
    • rememberSaveable giữ nguyên giá trị của văn bản trên các thay đổi về cấu hình.
    • Từ khoá by uỷ quyền giá trị của văn bản cho thuộc tính value của đối tượng MutableState.
  • OutlinedTextField gọi hàm filterText từ mô hình xem khi các thay đổi về văn bản kích hoạt lệnh gọi lại onValueChange.

Kết quả

Hình 1. Danh sách đã lọc sẽ cập nhật khi bạn nhập văn bản mới.

Các bộ sưu tập chứa hướng dẫn này

Hướng dẫn này là một phần của các bộ sưu tập Hướng dẫn nhanh được tuyển chọn này, bao gồm các mục tiêu phát triển Android rộng hơn:

Tìm hiểu cách triển khai các cách để người dùng tương tác với ứng dụng của bạn bằng cách nhập văn bản và sử dụng các phương thức nhập khác.

Bạn có câu hỏi hoặc ý kiến phản hồi

Hãy truy cập vào trang câu hỏi thường gặp để tìm hiểu về các hướng dẫn nhanh hoặc liên hệ với chúng tôi để cho chúng tôi biết suy nghĩ của bạn.