@@ -68,26 +68,33 @@ fun SearchBarExamples() {
6868 var currentExample by remember { mutableStateOf<String ?>(null ) }
6969
7070 when (currentExample) {
71- " basic " -> SearchBarBasicFilterList ()
72- " advanced " -> AppSearchBar ()
71+ " simple " -> SimpleSearchBarExample ()
72+ " fancy " -> CustomizableSearchBarExample ()
7373 else -> {
74- Button (onClick = { currentExample = " basic " }) {
75- Text (" Basic search bar with filter " )
74+ Button (onClick = { currentExample = " simple " }) {
75+ Text (" Simple SearchBar " )
7676 }
77- Button (onClick = { currentExample = " advanced " }) {
78- Text (" Advanced search bar with filter " )
77+ Button (onClick = { currentExample = " fancy " }) {
78+ Text (" Customizable SearchBar " )
7979 }
8080 }
8181 }
8282 }
8383}
8484
85+ // [START android_compose_components_simple_searchbar]
8586@OptIn(ExperimentalMaterial3Api ::class )
86- // [START android_compose_components_searchbarbasicfilterlist]
8787@Composable
88- fun SearchBarBasicFilterList (modifier : Modifier = Modifier ) {
89- var text by rememberSaveable { mutableStateOf(" " ) }
88+ fun SimpleSearchBar (
89+ query : String ,
90+ onQueryChange : (String ) -> Unit ,
91+ onSearch : (String ) -> Unit ,
92+ searchResults : List <String >,
93+ onResultClick : (String ) -> Unit ,
94+ modifier : Modifier = Modifier
95+ ) {
9096 var expanded by rememberSaveable { mutableStateOf(false ) }
97+
9198 Box (
9299 modifier
93100 .fillMaxSize()
@@ -99,26 +106,27 @@ fun SearchBarBasicFilterList(modifier: Modifier = Modifier) {
99106 .semantics { traversalIndex = 0f },
100107 inputField = {
101108 SearchBarDefaults .InputField (
102- query = text,
103- onQueryChange = { text = it },
104- onSearch = { expanded = false },
109+ query = query,
110+ onQueryChange = onQueryChange,
111+ onSearch = {
112+ onSearch(query)
113+ expanded = false
114+ },
105115 expanded = expanded,
106116 onExpandedChange = { expanded = it },
107- placeholder = { Text (" Hinted search text " ) }
117+ placeholder = { Text (" Search " ) }
108118 )
109119 },
110120 expanded = expanded,
111121 onExpandedChange = { expanded = it },
112122 ) {
113123 Column (Modifier .verticalScroll(rememberScrollState())) {
114- repeat(4 ) { index ->
115- val resultText = " Suggestion $index "
124+ searchResults.forEach { result ->
116125 ListItem (
117- headlineContent = { Text (resultText) },
118- supportingContent = { Text (" Additional info" ) },
126+ headlineContent = { Text (result) },
119127 modifier = Modifier
120128 .clickable {
121- text = resultText
129+ onResultClick(result)
122130 expanded = false
123131 }
124132 .fillMaxWidth()
@@ -128,27 +136,52 @@ fun SearchBarBasicFilterList(modifier: Modifier = Modifier) {
128136 }
129137 }
130138}
131- // [END android_compose_components_searchbarbasicfilterlist ]
139+ // [END android_compose_components_simple_searchbar ]
132140
133141@Preview(showBackground = true )
134142@Composable
135- private fun SearchBarBasicFilterListPreview () {
136- SearchBarBasicFilterList ()
143+ private fun SimpleSearchBarExample () {
144+ var query by rememberSaveable { mutableStateOf(" " ) }
145+ val items = listOf (
146+ " Cupcake" , " Donut" , " Eclair" , " Froyo" , " Gingerbread" , " Honeycomb" ,
147+ " Ice Cream Sandwich" , " Jelly Bean" , " KitKat" , " Lollipop"
148+ )
149+
150+ val filteredItems by remember {
151+ derivedStateOf {
152+ if (query.isEmpty()) {
153+ emptyList()
154+ } else {
155+ items.filter { it.contains(query, ignoreCase = true ) }
156+ }
157+ }
158+ }
159+
160+ SimpleSearchBar (
161+ query = query,
162+ onQueryChange = { query = it },
163+ onSearch = { /* Handle search submission */ },
164+ searchResults = filteredItems,
165+ onResultClick = { query = it }
166+ )
137167}
138168
139- // [START android_compose_components_searchbarfilterlist ]
169+ // [START android_compose_components_customizable_searchbar ]
140170@OptIn(ExperimentalMaterial3Api ::class )
141171@Composable
142- fun SearchBarFilterList (
143- list : List <String >,
172+ fun CustomizableSearchBar (
173+ query : String ,
174+ onQueryChange : (String ) -> Unit ,
175+ onSearch : (String ) -> Unit ,
176+ searchResults : List <String >,
177+ onResultClick : (String ) -> Unit ,
178+ placeholder : @Composable () -> Unit = { Text ("Search ") },
179+ leadingIcon : @Composable (() -> Unit )? = { Icon (Icons .Default .Search , contentDescription = "Search ") },
180+ trailingIcon : @Composable (() -> Unit )? = null,
181+ supportingContent : (@Composable (String ) -> Unit )? = null,
182+ leadingContent : (@Composable () -> Unit )? = null,
144183 modifier : Modifier = Modifier
145184) {
146- var text by rememberSaveable { mutableStateOf(" " ) }
147- val filteredList by remember {
148- derivedStateOf {
149- list.filter { it.lowercase().contains(text.lowercase()) }
150- }
151- }
152185 var expanded by rememberSaveable { mutableStateOf(false ) }
153186
154187 Box (
@@ -162,35 +195,33 @@ fun SearchBarFilterList(
162195 .semantics { traversalIndex = 0f },
163196 inputField = {
164197 SearchBarDefaults .InputField (
165- query = text,
166- onQueryChange = { text = it },
167- onSearch = { expanded = false },
198+ query = query,
199+ onQueryChange = onQueryChange,
200+ onSearch = {
201+ onSearch(query)
202+ expanded = false
203+ },
168204 expanded = expanded,
169205 onExpandedChange = { expanded = it },
170- placeholder = { Text ( " Hinted search text " ) } ,
171- leadingIcon = { Icon ( Icons . Default . Search , contentDescription = " Search " ) } ,
172- trailingIcon = { Icon ( Icons . Default . MoreVert , contentDescription = " More options " ) },
206+ placeholder = placeholder ,
207+ leadingIcon = leadingIcon ,
208+ trailingIcon = trailingIcon
173209 )
174210 },
175211 expanded = expanded,
176212 onExpandedChange = { expanded = it },
177213 ) {
178214 LazyColumn {
179- items(count = filteredList .size) { index ->
180- val resultText = filteredList [index]
215+ items(count = searchResults .size) { index ->
216+ val resultText = searchResults [index]
181217 ListItem (
182218 headlineContent = { Text (resultText) },
183- supportingContent = { Text (" Additional info" ) },
184- leadingContent = {
185- Icon (
186- Icons .Filled .Star ,
187- contentDescription = " Starred item"
188- )
189- },
219+ supportingContent = supportingContent?.let { { it(resultText) } },
220+ leadingContent = leadingContent,
190221 colors = ListItemDefaults .colors(containerColor = Color .Transparent ),
191222 modifier = Modifier
192223 .clickable {
193- text = resultText
224+ onResultClick( resultText)
194225 expanded = false
195226 }
196227 .fillMaxWidth()
@@ -199,6 +230,45 @@ fun SearchBarFilterList(
199230 }
200231 }
201232 }
233+ }
234+ }
235+ // [END android_compose_components_customizable_searchbar]
236+
237+ @Preview(showBackground = true )
238+ @Composable
239+ fun CustomizableSearchBarExample () {
240+ var query by rememberSaveable { mutableStateOf(" " ) }
241+ val items = listOf (
242+ " Cupcake" , " Donut" , " Eclair" , " Froyo" , " Gingerbread" , " Honeycomb" ,
243+ " Ice Cream Sandwich" , " Jelly Bean" , " KitKat" , " Lollipop" , " Marshmallow" ,
244+ " Nougat" , " Oreo" , " Pie"
245+ )
246+
247+ val filteredItems by remember {
248+ derivedStateOf {
249+ if (query.isEmpty()) {
250+ items
251+ } else {
252+ items.filter { it.contains(query, ignoreCase = true ) }
253+ }
254+ }
255+ }
256+
257+ Column (modifier = Modifier .fillMaxSize()) {
258+ CustomizableSearchBar (
259+ query = query,
260+ onQueryChange = { query = it },
261+ onSearch = { /* Handle search submission */ },
262+ searchResults = filteredItems,
263+ onResultClick = { query = it },
264+ placeholder = { Text (" Search desserts" ) },
265+ leadingIcon = { Icon (Icons .Default .Search , contentDescription = " Search" ) },
266+ trailingIcon = { Icon (Icons .Default .MoreVert , contentDescription = " More options" ) },
267+ supportingContent = { Text (" Android dessert" ) },
268+ leadingContent = { Icon (Icons .Filled .Star , contentDescription = " Starred item" ) }
269+ )
270+
271+ // Display the filtered list below the search bar
202272 LazyColumn (
203273 contentPadding = PaddingValues (
204274 start = 16 .dp,
@@ -211,34 +281,9 @@ fun SearchBarFilterList(
211281 traversalIndex = 1f
212282 },
213283 ) {
214- items(count = filteredList .size) {
215- Text (text = filteredList [it])
284+ items(count = filteredItems .size) {
285+ Text (text = filteredItems [it])
216286 }
217287 }
218288 }
219- }
220- // [END android_compose_components_searchbarfilterlist]
221-
222- @Preview(showBackground = true )
223- @Composable
224- fun AppSearchBar (modifier : Modifier = Modifier ) {
225- SearchBarFilterList (
226- list = listOf (
227- " Cupcake" ,
228- " Donut" ,
229- " Eclair" ,
230- " Froyo" ,
231- " Gingerbread" ,
232- " Honeycomb" ,
233- " Ice Cream Sandwich" ,
234- " Jelly Bean" ,
235- " KitKat" ,
236- " Lollipop" ,
237- " Marshmallow" ,
238- " Nougat" ,
239- " Oreo" ,
240- " Pie"
241- ),
242- modifier
243- )
244- }
289+ }
0 commit comments