Skip to content

Commit d751d51

Browse files
committed
Refactor search bar examples
1 parent 7d6ea31 commit d751d51

File tree

1 file changed

+119
-74
lines changed
  • compose/snippets/src/main/java/com/example/compose/snippets/components

1 file changed

+119
-74
lines changed

compose/snippets/src/main/java/com/example/compose/snippets/components/SearchBar.kt

Lines changed: 119 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)