Aby zaimplementować funkcję wyszukiwania, użyj paska wyszukiwania. Pasek wyszukiwania to trwałe pole wyszukiwania, w którym użytkownicy mogą wpisać słowo kluczowe lub frazę, aby wyświetlić odpowiednie wyniki w aplikacji. Jest on zalecany, gdy wyszukiwanie jest głównym elementem aplikacji.
Powierzchnia interfejsu API
Do implementowania pasków wyszukiwania używaj elementu SearchBar. Kluczowe parametry tego elementu obejmują:
inputField: Definiuje pole do wprowadzania danych na pasku wyszukiwania. Zwykle używaSearchBarDefaults.InputField, który umożliwia dostosowanie:query: tekst zapytania, który ma się wyświetlać w polu do wprowadzania danych.onQueryChange: lambda do obsługi zmian w ciągu zapytania.
expanded: wartość logiczna wskazująca, czy pasek wyszukiwania jest rozwinięty, aby wyświetlać sugestie lub przefiltrowane wyniki.onExpandedChange: lambda do obsługi zmian stanu rozwinięcia listy.content: treść tego paska wyszukiwania, która ma wyświetlać wyniki wyszukiwania poniżejinputField.
Pasek wyszukiwania z sugestiami
Ten fragment kodu pokazuje podstawową implementację SearchBar z sugestiami:
@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() ) } } } } }
Najważniejsze informacje o kodzie
rememberSaveablezapewnia, że stan rozwinięcia lub zwinięcia paska wyszukiwania zostanie zachowany po zmianach konfiguracji. Zapisuje zapamiętaną wartość w pakieciesavedInstanceStateaktywności hosta, zanim aktywność zostanie zniszczona podczas zmiany konfiguracji.- Modyfikator
semanticsokreśla kolejność przechodzenia TalkBack.isTraversalGroupjest ustawiony dlaBox, aby grupować wszystkie podrzędne elementy.traversalIndexjest ustawiony tak, aby określać kolejność, w jakiej TalkBack odczytuje informacje o ułatwieniach dostępu z każdego elementu w grupie. TalkBack odczytuje informacje o ułatwieniach dostępu w przypadku elementu z wartością ujemną, np.-1, przed elementem z wartością dodatnią, np.1. Ponieważ wartość jest liczbą zmiennoprzecinkową, możesz określić niestandardową kolejność wielu elementów, ustawiając wartości między-1.0a1.0w każdym elemencie.
SearchBarzawierainputFielddo wprowadzania danych wejściowych użytkownika orazColumndo wyświetlania sugestii wyszukiwania.SearchBarDefaults.InputFieldtworzy pole do wprowadzania danych i obsługuje zmiany w zapytaniu użytkownika.onQueryChangeobsługuje wprowadzanie tekstu i aktualizuje stan za każdym razem, gdy tekst w polu do wprowadzania danych się zmienia.The expandedstan określa widoczność listy sugestii.
searchResults.forEach { result -> … }iteruje posearchResultsliście i tworzyListItemdla każdego wyniku.- Gdy klikniesz
ListItem, zaktualizuje siętextFieldState, pasek wyszukiwania zostanie zwinięty, atextFieldzostanie wypełniony wybranym wynikiem wyszukiwania.
- Gdy klikniesz
Wynik
Pasek wyszukiwania z przefiltrowaną listą
Ten przykład pokazuje SearchBar, który filtruje listę na podstawie zapytania użytkownika:
@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: @Composable (() -> Unit)? = { Icon(Icons.Default.Search, contentDescription = "Search") }, trailingIcon: @Composable (() -> Unit)? = null, supportingContent: (@Composable (String) -> Unit)? = null, leadingContent: (@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 = 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) ) } } } } }
Najważniejsze informacje o kodzie
- Funkcja lambda
onQueryChangejest wywoływana za każdym razem, gdy użytkownik wpisuje lub usuwa tekst na pasku wyszukiwania. SearchBarDefaults.InputFieldzawieraleadingIcon, który dodaje ikonę wyszukiwania na początku pola do wprowadzania danych, oraztrailingIcon, który dodaje ikonę „więcej opcji” na końcu pola do wprowadzania danych. W tym miejscu możesz udostępnić użytkownikowi opcje sortowania i filtrowania.onSearch = { … }wywołuje lambdęonSearchi zwija pasek wyszukiwania po przesłaniu wyszukiwania.LazyColumnwydajnie obsługuje potencjalnie dużą liczbę wyników wyszukiwania. Iteruje po liściesearchResultsi wyświetla każdy wynik jakoListItem.- Każdy element
ListItemwyświetla tekst elementu, tekst z dodatkowymi informacjami oraz ikonę gwiazdki jakoleadingContentelementu. W tym przykładzie jest dostępna opcja dodania elementu do ulubionych. - Logikę filtrowania znajdziesz w
CustomizableSearchBarExamplew pełnym kodzie źródłowym na GitHubie.
Wynik
Dodatkowe materiały
- Material Design: pasek wyszukiwania