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 liên tục cho phép người dùng nhập một từ khoá hoặc cụm từ để hiển thị kết quả có liên quan trong ứng dụng của bạn. Bạn nên sử dụng thanh tìm kiếm khi hoạt độ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 của thanh tìm kiếm. Lớp này thường sử dụngSearchBarDefaults.InputField
, cho phép tuỳ chỉnh:query
: Văn bản truy vấn sẽ xuất hiện trong trường nhập.onQueryChange
: Lambda để xử lý các thay đổi trong chuỗi truy vấn.
expanded
: Giá trị boolean cho biết thanh tìm kiếm có được mở rộng để hiển thị các đề xuất hay kết quả đã lọc hay không.onExpandedChange
: 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ó nội dung đề xuất
Đoạn mã này cho thấy cách triển khai cơ bản của SearchBar
với các đề 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 thanh tìm kiếm được mở rộng hay thu gọn sẽ được giữ nguyên trong các thay đổi về cấu hình. Phương thức này ghi giá trị đã ghi nhớ vào góisavedInstanceState
củ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
semantics
kiểm soát thứ tự di chuyển của TalkBack.isTraversalGroup
được đặt choBox
để nhóm tất cả các thành phần kết hợp con.traversalIndex
được đặt để chỉ định thứ tự TalkBack đọc thông tin hỗ trợ tiếp cận từ mỗi thiết bị đồng cấp trong nhóm. TalkBack đọc thông tin hỗ trợ tiếp cận trên một đối tượng có giá trị âm, chẳng hạn như-1
, trước một đối tượng có giá trị dương, chẳng hạn như1
. Vì giá trị này là float, nên bạn có thể chỉ định thứ tự tuỳ chỉnh của nhiều máy ngang hàng bằng cách đặt giá trị trong khoảng từ-1.0
đến1.0
trên mỗi máy ngang hàng.
SearchBar
chứainputField
để nhập dữ liệu của người dùng vàColumn
để hiển thị các đề xuất tìm kiếm.SearchBarDefaults.InputField
tạo trường nhập và xử lý các thay đổi đối với truy vấn của người dùng.onQueryChange
xử lý hoạt động 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 thay đổi.- Trạng thái
The expanded
kiểm soát chế độ hiển thị của danh sách đề xuất.
searchResults.forEach { result -> … }
lặp lại qua danh sáchsearchResults
và tạo mộtListItem
cho mỗi kết quả.- Khi nhấp vào
ListItem
, thao tác này sẽ cập nhậttextFieldState
, thu gọn thanh tìm kiếm và điền kết quả tìm kiếm đã chọn vàotextField
.
- Khi nhấp vào
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 truy vấn 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, // Customization options placeholder: @Composable () -> Unit = { Text("Search") }, leadingIcon: @Composable (() -> Unit)? = { Icon(Icons.Default.Search, contentDescription = "Search") }, trailingIcon: @Composable (() -> Unit)? = null, supportingContent: (@Composable (String) -> Unit)? = null, leadingContent: (@Composable () -> Unit)? = null, modifier: Modifier = Modifier ) { // 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 = searchResults.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) ) } } } } }
Các điểm chính về mã
- Hàm lambda
onQueryChange
được gọi mỗi khi người dùng nhập hoặc xoá văn bản trong thanh tìm kiếm. SearchBarDefaults.InputField
chứ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 "lựa 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 cho người dùng các tuỳ chọn sắp xếp và lọc.onSearch = { … }
gọi lambdaonSearch
và thu gọn thanh tìm kiếm khi nội dung tìm kiếm được gửi.LazyColumn
xử 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áchsearchResults
và hiển thị từng kết quả dưới dạngListItem
.- Mỗi thành phần kết hợp
ListItem
hiển thị văn bản của mặt hàng, văn bản hiển thị thông tin bổ sung và biểu tượng ngôi sao dưới dạngleadingContent
của mặt hàng. Trong ví dụ này, một tuỳ chọn để thêm mục vào mục yêu thích sẽ xuất hiện. - Để biết logic lọc, hãy xem
CustomizableSearchBarExample
trong mã nguồn đầy đủ trên GitHub.
Kết quả

Tài nguyên khác
- Material Design: Thanh tìm kiếm