Skip to content

Commit 73361f7

Browse files
authored
Merge branch 'main' into swipe-reveal
2 parents c28b438 + e6997d9 commit 73361f7

File tree

4 files changed

+269
-22
lines changed

4 files changed

+269
-22
lines changed

compose/snippets/src/main/java/com/example/compose/snippets/SnippetsActivity.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import com.example.compose.snippets.components.MenusExamples
4646
import com.example.compose.snippets.components.PartialBottomSheet
4747
import com.example.compose.snippets.components.ProgressIndicatorExamples
4848
import com.example.compose.snippets.components.ScaffoldExample
49+
import com.example.compose.snippets.components.SearchBarExamples
4950
import com.example.compose.snippets.components.SegmentedButtonExamples
5051
import com.example.compose.snippets.components.SliderExamples
5152
import com.example.compose.snippets.components.SwipeToDismissBoxExamples
@@ -123,6 +124,7 @@ class SnippetsActivity : ComponentActivity() {
123124
TopComponentsDestination.NavigationDrawerExamples -> NavigationDrawerExamples()
124125
TopComponentsDestination.SegmentedButtonExamples -> SegmentedButtonExamples()
125126
TopComponentsDestination.SwipeToDismissBoxExamples -> SwipeToDismissBoxExamples()
127+
TopComponentsDestination.SearchBarExamples -> SearchBarExamples()
126128
}
127129
}
128130
}
Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,244 @@
1+
/*
2+
* Copyright 2024 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.example.compose.snippets.components
18+
19+
import androidx.compose.foundation.clickable
20+
import androidx.compose.foundation.layout.Arrangement
21+
import androidx.compose.foundation.layout.Box
22+
import androidx.compose.foundation.layout.Column
23+
import androidx.compose.foundation.layout.PaddingValues
24+
import androidx.compose.foundation.layout.fillMaxSize
25+
import androidx.compose.foundation.layout.fillMaxWidth
26+
import androidx.compose.foundation.layout.padding
27+
import androidx.compose.foundation.lazy.LazyColumn
28+
import androidx.compose.foundation.rememberScrollState
29+
import androidx.compose.foundation.verticalScroll
30+
import androidx.compose.material.icons.Icons
31+
import androidx.compose.material.icons.filled.MoreVert
32+
import androidx.compose.material.icons.filled.Search
33+
import androidx.compose.material.icons.filled.Star
34+
import androidx.compose.material3.Button
35+
import androidx.compose.material3.ExperimentalMaterial3Api
36+
import androidx.compose.material3.Icon
37+
import androidx.compose.material3.ListItem
38+
import androidx.compose.material3.ListItemDefaults
39+
import androidx.compose.material3.SearchBar
40+
import androidx.compose.material3.SearchBarDefaults
41+
import androidx.compose.material3.Text
42+
import androidx.compose.runtime.Composable
43+
import androidx.compose.runtime.derivedStateOf
44+
import androidx.compose.runtime.getValue
45+
import androidx.compose.runtime.mutableStateOf
46+
import androidx.compose.runtime.remember
47+
import androidx.compose.runtime.saveable.rememberSaveable
48+
import androidx.compose.runtime.setValue
49+
import androidx.compose.ui.Alignment
50+
import androidx.compose.ui.Modifier
51+
import androidx.compose.ui.graphics.Color
52+
import androidx.compose.ui.semantics.isTraversalGroup
53+
import androidx.compose.ui.semantics.semantics
54+
import androidx.compose.ui.semantics.traversalIndex
55+
import androidx.compose.ui.tooling.preview.Preview
56+
import androidx.compose.ui.unit.dp
57+
58+
@Preview
59+
@Composable
60+
fun SearchBarExamples() {
61+
Column(
62+
modifier = Modifier
63+
.padding(16.dp)
64+
.fillMaxSize(),
65+
verticalArrangement = Arrangement.spacedBy(24.dp),
66+
horizontalAlignment = Alignment.CenterHorizontally,
67+
) {
68+
var currentExample by remember { mutableStateOf<String?>(null) }
69+
70+
when (currentExample) {
71+
"basic" -> SearchBarBasicFilterList()
72+
"advanced" -> AppSearchBar()
73+
else -> {
74+
Button(onClick = { currentExample = "basic" }) {
75+
Text("Basic search bar with filter")
76+
}
77+
Button(onClick = { currentExample = "advanced" }) {
78+
Text("Advanced search bar with filter")
79+
}
80+
}
81+
}
82+
}
83+
}
84+
85+
@OptIn(ExperimentalMaterial3Api::class)
86+
// [START android_compose_components_searchbarbasicfilterlist]
87+
@Composable
88+
fun SearchBarBasicFilterList(modifier: Modifier = Modifier) {
89+
var text by rememberSaveable { mutableStateOf("") }
90+
var expanded by rememberSaveable { mutableStateOf(false) }
91+
Box(
92+
modifier
93+
.fillMaxSize()
94+
.semantics { isTraversalGroup = true }
95+
) {
96+
SearchBar(
97+
modifier = Modifier
98+
.align(Alignment.TopCenter)
99+
.semantics { traversalIndex = 0f },
100+
inputField = {
101+
SearchBarDefaults.InputField(
102+
query = text,
103+
onQueryChange = { text = it },
104+
onSearch = { expanded = false },
105+
expanded = expanded,
106+
onExpandedChange = { expanded = it },
107+
placeholder = { Text("Hinted search text") }
108+
)
109+
},
110+
expanded = expanded,
111+
onExpandedChange = { expanded = it },
112+
) {
113+
Column(Modifier.verticalScroll(rememberScrollState())) {
114+
repeat(4) { index ->
115+
val resultText = "Suggestion $index"
116+
ListItem(
117+
headlineContent = { Text(resultText) },
118+
supportingContent = { Text("Additional info") },
119+
modifier = Modifier
120+
.clickable {
121+
text = resultText
122+
expanded = false
123+
}
124+
.fillMaxWidth()
125+
)
126+
}
127+
}
128+
}
129+
}
130+
}
131+
// [END android_compose_components_searchbarbasicfilterlist]
132+
133+
@Preview(showBackground = true)
134+
@Composable
135+
private fun SearchBarBasicFilterListPreview() {
136+
SearchBarBasicFilterList()
137+
}
138+
139+
// [START android_compose_components_searchbarfilterlist]
140+
@OptIn(ExperimentalMaterial3Api::class)
141+
@Composable
142+
fun SearchBarFilterList(
143+
list: List<String>,
144+
modifier: Modifier = Modifier
145+
) {
146+
var text by rememberSaveable { mutableStateOf("") }
147+
val filteredList by remember {
148+
derivedStateOf {
149+
list.filter { it.lowercase().contains(text.lowercase()) }
150+
}
151+
}
152+
var expanded by rememberSaveable { mutableStateOf(false) }
153+
154+
Box(
155+
modifier
156+
.fillMaxSize()
157+
.semantics { isTraversalGroup = true }
158+
) {
159+
SearchBar(
160+
modifier = Modifier
161+
.align(Alignment.TopCenter)
162+
.semantics { traversalIndex = 0f },
163+
inputField = {
164+
SearchBarDefaults.InputField(
165+
query = text,
166+
onQueryChange = { text = it },
167+
onSearch = { expanded = false },
168+
expanded = expanded,
169+
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") },
173+
)
174+
},
175+
expanded = expanded,
176+
onExpandedChange = { expanded = it },
177+
) {
178+
LazyColumn {
179+
items(count = filteredList.size) { index ->
180+
val resultText = filteredList[index]
181+
ListItem(
182+
headlineContent = { Text(resultText) },
183+
supportingContent = { Text("Additional info") },
184+
leadingContent = {
185+
Icon(
186+
Icons.Filled.Star,
187+
contentDescription = "Starred item"
188+
)
189+
},
190+
colors = ListItemDefaults.colors(containerColor = Color.Transparent),
191+
modifier = Modifier
192+
.clickable {
193+
text = resultText
194+
expanded = false
195+
}
196+
.fillMaxWidth()
197+
.padding(horizontal = 16.dp, vertical = 4.dp)
198+
)
199+
}
200+
}
201+
}
202+
LazyColumn(
203+
contentPadding = PaddingValues(
204+
start = 16.dp,
205+
top = 72.dp,
206+
end = 16.dp,
207+
bottom = 16.dp
208+
),
209+
verticalArrangement = Arrangement.spacedBy(8.dp),
210+
modifier = Modifier.semantics {
211+
traversalIndex = 1f
212+
},
213+
) {
214+
items(count = filteredList.size) {
215+
Text(text = filteredList[it])
216+
}
217+
}
218+
}
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+
}

compose/snippets/src/main/java/com/example/compose/snippets/navigation/Destination.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,5 @@ enum class TopComponentsDestination(val route: String, val title: String) {
5151
NavigationDrawerExamples("navigationDrawerExamples", "Navigation drawer"),
5252
SegmentedButtonExamples("segmentedButtonExamples", "Segmented button"),
5353
SwipeToDismissBoxExamples("swipeToDismissBoxExamples", "Swipe to dismiss box examples")
54+
SearchBarExamples("searchBarExamples", "Search bar")
5455
}

gradle/libs.versions.toml

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ accompanist = "0.36.0"
33
androidGradlePlugin = "8.7.3"
44
androidx-activity-compose = "1.9.3"
55
androidx-appcompat = "1.7.0"
6-
androidx-compose-bom = "2024.11.00"
6+
androidx-compose-bom = "2024.12.01"
77
androidx-compose-ui-test = "1.7.0-alpha08"
88
androidx-constraintlayout = "2.2.0"
99
androidx-constraintlayout-compose = "1.1.0"
@@ -14,48 +14,48 @@ androidx-fragment-ktx = "1.8.5"
1414
androidx-glance-appwidget = "1.1.1"
1515
androidx-lifecycle-compose = "2.8.7"
1616
androidx-lifecycle-runtime-compose = "2.8.7"
17-
androidx-navigation = "2.8.4"
18-
androidx-paging = "3.3.4"
17+
androidx-navigation = "2.8.5"
18+
androidx-paging = "3.3.5"
1919
androidx-test = "1.6.1"
2020
androidx-test-espresso = "3.6.1"
2121
androidx-window = "1.3.0"
2222
androidxHiltNavigationCompose = "1.2.0"
2323
coil = "2.7.0"
2424
# @keep
2525
compileSdk = "35"
26-
compose-latest = "1.7.5"
26+
compose-latest = "1.7.6"
2727
composeUiTooling = "1.4.0"
2828
coreSplashscreen = "1.0.1"
2929
coroutines = "1.9.0"
3030
glide = "1.0.0-beta01"
3131
google-maps = "19.0.0"
3232
gradle-versions = "0.51.0"
33-
guava = "33.2.1-android"
34-
hilt = "2.52"
35-
horologist = "0.6.20"
33+
guava = "33.4.0-jre"
34+
hilt = "2.53.1"
35+
horologist = "0.6.22"
3636
junit = "4.13.2"
37-
kotlin = "2.0.21"
37+
kotlin = "2.1.0"
3838
kotlinxSerializationJson = "1.7.3"
39-
ksp = "2.0.21-1.0.26"
40-
maps-compose = "6.2.0"
41-
material = "1.13.0-alpha07"
39+
ksp = "2.1.0-1.0.29"
40+
maps-compose = "6.4.0"
41+
material = "1.13.0-alpha08"
4242
material3-adaptive = "1.0.0"
4343
material3-adaptive-navigation-suite = "1.3.1"
44-
media3 = "1.4.1"
44+
media3 = "1.5.0"
4545
# @keep
4646
minSdk = "21"
47-
playServicesWearable = "18.2.0"
48-
protolayout = "1.3.0-alpha04"
49-
protolayoutExpression = "1.3.0-alpha04"
50-
protolayoutMaterial = "1.3.0-alpha04"
47+
playServicesWearable = "19.0.0"
48+
protolayout = "1.3.0-alpha05"
49+
protolayoutExpression = "1.3.0-alpha05"
50+
protolayoutMaterial = "1.3.0-alpha05"
5151
recyclerview = "1.3.2"
5252
# @keep
5353
targetSdk = "34"
54-
tiles = "1.5.0-alpha04"
55-
tilesRenderer = "1.5.0-alpha04"
56-
tilesTesting = "1.5.0-alpha04"
57-
tilesTooling = "1.5.0-alpha04"
58-
tilesToolingPreview = "1.5.0-alpha04"
54+
tiles = "1.5.0-alpha05"
55+
tilesRenderer = "1.5.0-alpha05"
56+
tilesTesting = "1.5.0-alpha05"
57+
tilesTooling = "1.5.0-alpha05"
58+
tilesToolingPreview = "1.5.0-alpha05"
5959
version-catalog-update = "0.8.5"
6060
wear = "1.3.0"
6161
wearComposeFoundation = "1.4.0"
@@ -64,7 +64,7 @@ wearToolingPreview = "1.0.0"
6464

6565
[libraries]
6666
accompanist-adaptive = { module = "com.google.accompanist:accompanist-adaptive", version.ref = "accompanist" }
67-
accompanist-permissions = { module = "com.google.accompanist:accompanist-permissions", version.ref = "accompanist" }
67+
accompanist-permissions = "com.google.accompanist:accompanist-permissions:0.37.0"
6868
accompanist-theme-adapter-appcompat = { module = "com.google.accompanist:accompanist-themeadapter-appcompat", version.ref = "accompanist" }
6969
accompanist-theme-adapter-material = { module = "com.google.accompanist:accompanist-themeadapter-material", version.ref = "accompanist" }
7070
accompanist-theme-adapter-material3 = { module = "com.google.accompanist:accompanist-themeadapter-material3", version.ref = "accompanist" }

0 commit comments

Comments
 (0)