Sử dụng thanh tìm kiếm để triển khai chức năng tìm kiếm. Thanh tìm kiếm là một trường tìm kiếm cố định, cho phép người dùng nhập từ khoá hoặc cụm từ để hiển thị kết quả liên quan trong ứng dụng của bạn. Bạn nên dùng thanh tìm kiếm khi tính năng tìm kiếm là trọng tâm chính của ứng dụng.
Nền tảng API
Sử dụng thành phần kết hợp SearchBar để triển khai thanh tìm kiếm. Các tham số chính cho thành phần kết hợp này bao gồm:
inputField: Xác định trường nhập dữ liệu của thanh tìm kiếm. Thành phần này thường sử dụngSearchBarDefaults.InputField, cho phép tuỳ chỉnh:query: Văn bản của cụm từ tìm kiếm sẽ xuất hiện trong trường nhập dữ liệu.onQueryChange: Lambda để xử lý các thay đổi trong chuỗi truy vấn.
expanded: Một boolean cho biết thanh tìm kiếm có được mở rộng để hiển thị các đề xuất hoặc kết quả đã lọc hay không.onExpandedChange: Hàm lambda để xử lý các thay đổi trong trạng thái mở rộng của trình đơn thả xuống.content: Nội dung của thanh tìm kiếm này để hiển thị kết quả tìm kiếm bên dướiinputField.
Thanh tìm kiếm có các cụm từ đề xuất
Đoạn mã này cho thấy cách triển khai cơ bản của SearchBar kèm theo nội dung đề xuất:
@OptIn(ExperimentalMaterial3Api::class) @Composable fun SimpleSearchBar( textFieldState: TextFieldState, onSearch: (String) -> Unit, searchResults: List<String>, modifier: Modifier = Modifier ) { // Controls expansion state of the search bar var expanded by rememberSaveable { mutableStateOf(false) } Box( modifier .fillMaxSize() .semantics { isTraversalGroup = true } ) { SearchBar( modifier = Modifier .align(Alignment.TopCenter) .semantics { traversalIndex = 0f }, inputField = { SearchBarDefaults.InputField( query = textFieldState.text.toString(), onQueryChange = { textFieldState.edit { replace(0, length, it) } }, onSearch = { onSearch(textFieldState.text.toString()) expanded = false }, expanded = expanded, onExpandedChange = { expanded = it }, placeholder = { Text("Search") } ) }, expanded = expanded, onExpandedChange = { expanded = it }, ) { // Display search results in a scrollable column Column(Modifier.verticalScroll(rememberScrollState())) { searchResults.forEach { result -> ListItem( headlineContent = { Text(result) }, modifier = Modifier .clickable { textFieldState.edit { replace(0, length, result) } expanded = false } .fillMaxWidth() ) } } } } }
Các điểm chính về mã
rememberSaveableđảm bảo rằng trạng thái mở rộng hoặc thu gọn của thanh tìm kiếm được giữ nguyên khi có thay đổi về cấu hình. Hàm này ghi giá trị đã ghi nhớ vào góisavedInstanceStatecủa Hoạt động lưu trữ trước khi Hoạt động bị huỷ trong quá trình thay đổi cấu hình.- Đối tượng sửa đổi
semanticskiểm soát thứ tự duyệt qua của TalkBack.isTraversalGroupđược đặt choBoxđể nhóm tất cả thành phần kết hợp con của thành phần này.traversalIndexđược đặt để chỉ định thứ tự TalkBack đọc thông tin hỗ trợ tiếp cận từ mỗi nhóm ngang hàng. TalkBack đọc thông tin hỗ trợ tiếp cận trên một ứng dụng ngang hàng có giá trị âm, chẳng hạn như-1, trước một ứng dụng ngang hàng có giá trị dương, chẳng hạn như1. Vì giá trị là số thực, nên bạn có thể chỉ định thứ tự tuỳ chỉnh của nhiều thành phần đồng cấp bằng cách đặt giá trị trong khoảng từ-1.0đến1.0trên mỗi thành phần đồng cấp.
SearchBarchứainputFieldcho dữ liệu đầu vào của người dùng vàColumnđể hiển thị cụm từ tìm kiếm được đề xuất.SearchBarDefaults.InputFieldtạo trường nhập dữ liệu và xử lý các thay đổi đối với cụm từ tìm kiếm của người dùng.onQueryChangexử lý dữ liệu nhập văn bản và cập nhật trạng thái bất cứ khi nào văn bản trong trường nhập dữ liệu thay đổi.- Trạng thái
expandedkiểm soát chế độ hiển thị của danh sách đề xuất.
searchResults.forEach { result -> … }lặp lại qua danh sáchsearchResultsvà tạo mộtListItemcho mỗi kết quả.- Khi người dùng nhấp vào một
ListItem, thao tác này sẽ cập nhậttextFieldState, thu gọn thanh tìm kiếm và điềntextFieldbằng kết quả tìm kiếm đã chọn.
- Khi người dùng nhấp vào một
Kết quả
Thanh tìm kiếm có danh sách được lọc
Ví dụ này cho thấy một SearchBar lọc danh sách dựa trên cụm từ tìm kiếm của người dùng:
@OptIn(ExperimentalMaterial3Api::class) @Composable fun CustomizableSearchBar( query: String, onQueryChange: (String) -> Unit, onSearch: (String) -> Unit, searchResults: List<String>, onResultClick: (String) -> Unit, modifier: Modifier = Modifier, // Customization options placeholder: @Composable () -> Unit = { Text("Search") }, leadingIcon: @Compos>able (() - Unit)? = { Icon(Icons.Default.Search, contentDescription = "Search") }, trailingIco>n: @Composable (() - Unit)? = null, supportingContent: (@C>omposable (String) - Unit)? = null, leadingConten>t: (@Composable () - Unit)? = null, ) { // Track expanded state of search bar var expanded by rememberSaveable { mutableStateOf(false) } Box( modifier .fillMaxSize() .semantics { isTraversalGroup = true } ) { SearchBar( modifier = Modifier .align(Alignment.TopCenter) .semantics { traversalIndex = 0f }, inputField = { // Customizable input field implementation SearchBarDefaults.InputField( query = query, onQueryChange = onQueryChange, onSearch = { onSearch(query) expanded = false }, expanded = expanded, onExpandedChange = { expanded = it }, placeholder = placeholder, leadingIcon = leadingIcon, trailingIcon = trailingIcon ) }, expanded = expanded, onExpandedChange = { expanded = it }, ) { // Show search results in a lazy column for better performance LazyColumn { items(count = searchRes>ults.size) { index - val resultText = searchResults[index] ListItem( headlineContent = { Text(resultText) }, supportingContent = supportingContent?.let { { it(resultText) } }, leadingContent = leadingContent, colors = ListItemDefaults.colors(containerColor = Color.Transparent), modifier = Modifier .clickable { onResultClick(resultText) expanded = false } .fillMaxWidth() .padding(horizontal = 16.dp, vertical = 4.dp) ) } } }SearchBar.kt
Các điểm chính về mã
- Hàm lambda
onQueryChangeđược gọi bất cứ khi nào người dùng nhập hoặc xoá văn bản trong thanh tìm kiếm. SearchBarDefaults.InputFieldchứaleadingIcon, giúp thêm biểu tượng tìm kiếm vào đầu trường nhập dữ liệu vàtrailingIcon, giúp thêm biểu tượng "tuỳ chọn khác" vào cuối trường nhập dữ liệu. Tại đây, bạn có thể cung cấp các lựa chọn sắp xếp và lọc cho người dùng.onSearch = { … }gọi lambdaonSearchvà thu gọn thanh tìm kiếm khi nội dung tìm kiếm được gửi.LazyColumnxử lý hiệu quả một số lượng lớn kết quả tìm kiếm. Hàm này lặp lại qua danh sáchsearchResultsvà hiển thị từng kết quả dưới dạngListItem.- Mỗi composable
ListItemhiển thị văn bản của mục, văn bản hiển thị thông tin bổ sung và biểu tượng dấu sao dưới dạngleadingContentcủa mục. Trong ví dụ này, bạn sẽ thấy một lựa chọn để thêm mục vào danh sách yêu thích. - Để biết logic lọc, hãy xem
CustomizableSearchBarExampletrong mã nguồn đầy đủ trên GitHub.
Kết quả
Tài nguyên khác
- Material Design: Thanh tìm kiếm