Skip to content

Commit 95e6d36

Browse files
committed
Add Swipe to reveal examples
1 parent c79a414 commit 95e6d36

File tree

1 file changed

+304
-0
lines changed

1 file changed

+304
-0
lines changed
Lines changed: 304 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,304 @@
1+
package com.example.compose.snippets.components
2+
3+
import androidx.compose.animation.animateColorAsState
4+
import androidx.compose.foundation.background
5+
import androidx.compose.foundation.layout.Arrangement
6+
import androidx.compose.foundation.layout.Row
7+
import androidx.compose.foundation.layout.Spacer
8+
import androidx.compose.foundation.layout.fillMaxSize
9+
import androidx.compose.foundation.layout.padding
10+
import androidx.compose.foundation.lazy.LazyColumn
11+
import androidx.compose.foundation.lazy.items
12+
import androidx.compose.material.icons.Icons
13+
import androidx.compose.material.icons.filled.CheckBox
14+
import androidx.compose.material.icons.filled.CheckBoxOutlineBlank
15+
import androidx.compose.material.icons.filled.Delete
16+
import androidx.compose.material3.Icon
17+
import androidx.compose.material3.ListItem
18+
import androidx.compose.material3.OutlinedCard
19+
import androidx.compose.material3.SwipeToDismissBox
20+
import androidx.compose.material3.SwipeToDismissBoxValue
21+
import androidx.compose.material3.Text
22+
import androidx.compose.material3.rememberSwipeToDismissBoxState
23+
import androidx.compose.runtime.Composable
24+
import androidx.compose.runtime.getValue
25+
import androidx.compose.runtime.mutableStateListOf
26+
import androidx.compose.runtime.remember
27+
import androidx.compose.ui.Alignment
28+
import androidx.compose.ui.Modifier
29+
import androidx.compose.ui.graphics.Color
30+
import androidx.compose.ui.graphics.RectangleShape
31+
import androidx.compose.ui.graphics.lerp
32+
import androidx.compose.ui.tooling.preview.Preview
33+
import androidx.compose.ui.unit.dp
34+
35+
// [START android_compose_components_todoitem]
36+
data class TodoItem(
37+
var isItemDone: Boolean,
38+
var itemDescription: String
39+
)
40+
// [END android_compose_components_todoitem]
41+
42+
// [START android_compose_components_swipeitem]
43+
@Composable
44+
fun SwipeItem(
45+
value: TodoItem,
46+
startToEndAction: (TodoItem) -> Unit,
47+
endToStartAction: (TodoItem) -> Unit,
48+
modifier: Modifier = Modifier,
49+
content: @Composable (TodoItem) -> Unit
50+
) {
51+
val swipeToDismissBoxState = rememberSwipeToDismissBoxState(
52+
confirmValueChange = {
53+
when (it) {
54+
SwipeToDismissBoxValue.StartToEnd -> {
55+
startToEndAction(value)
56+
// Do not dismiss this item.
57+
false
58+
}
59+
SwipeToDismissBoxValue.EndToStart -> {
60+
endToStartAction(value)
61+
true
62+
}
63+
SwipeToDismissBoxValue.Settled -> {
64+
false
65+
}
66+
}
67+
}
68+
)
69+
70+
SwipeToDismissBox(
71+
state = swipeToDismissBoxState,
72+
modifier = modifier
73+
.fillMaxSize(),
74+
backgroundContent = {
75+
Row(
76+
modifier = Modifier
77+
.background(
78+
when (swipeToDismissBoxState.dismissDirection) {
79+
SwipeToDismissBoxValue.StartToEnd -> {
80+
Color.Blue
81+
}
82+
SwipeToDismissBoxValue.EndToStart -> {
83+
Color.Red
84+
}
85+
SwipeToDismissBoxValue.Settled -> {
86+
Color.LightGray
87+
}
88+
}
89+
)
90+
.fillMaxSize(),
91+
verticalAlignment = Alignment.CenterVertically,
92+
horizontalArrangement = Arrangement.SpaceBetween
93+
) {
94+
when (swipeToDismissBoxState.dismissDirection) {
95+
SwipeToDismissBoxValue.StartToEnd -> {
96+
if (value.isItemDone) {
97+
Icon(
98+
imageVector = Icons.Default.CheckBox,
99+
contentDescription = "Item done",
100+
tint = Color.White,
101+
modifier = Modifier
102+
.padding(12.dp)
103+
)
104+
} else {
105+
Icon(
106+
imageVector = Icons.Default.CheckBoxOutlineBlank,
107+
contentDescription = "Item not done",
108+
tint = Color.White,
109+
modifier = Modifier
110+
.padding(12.dp)
111+
)
112+
}
113+
}
114+
115+
SwipeToDismissBoxValue.EndToStart -> {
116+
Spacer(modifier = Modifier)
117+
Icon(
118+
imageVector = Icons.Default.Delete,
119+
contentDescription = "Remove item",
120+
tint = Color.White,
121+
modifier = Modifier
122+
.padding(12.dp)
123+
)
124+
}
125+
126+
SwipeToDismissBoxValue.Settled -> {}
127+
}
128+
}
129+
}
130+
) {
131+
content(value)
132+
}
133+
}
134+
// [END android_compose_components_swipeitem]
135+
136+
@Preview(showBackground = true)
137+
// [START android_compose_components_swipeitemexample]
138+
@Composable
139+
private fun SwipeItemExample() {
140+
val todoItems = remember {
141+
mutableStateListOf(
142+
TodoItem(isItemDone = false, itemDescription = "Pay bills"),
143+
TodoItem(isItemDone = false, itemDescription = "Buy groceries"),
144+
TodoItem(isItemDone = false, itemDescription = "Go to gym"),
145+
TodoItem(isItemDone = false, itemDescription = "Get dinner")
146+
)
147+
}
148+
149+
LazyColumn {
150+
items(
151+
items = todoItems,
152+
key = { it.itemDescription }
153+
) { todoItem ->
154+
SwipeItem(
155+
value = todoItem,
156+
startToEndAction = {
157+
todoItem.isItemDone = !todoItem.isItemDone
158+
},
159+
endToStartAction = {
160+
todoItems -= todoItem
161+
}
162+
) {
163+
ListItem(
164+
headlineContent = { Text(text = todoItem.itemDescription) },
165+
supportingContent = { Text(text = "swipe me to update or remove.") }
166+
)
167+
}
168+
}
169+
}
170+
}
171+
// [END android_compose_components_swipeitemexample]
172+
173+
// [START android_compose_components_swipecarditem]
174+
@Composable
175+
fun SwipeCardItem(
176+
value: TodoItem,
177+
startToEndAction: (TodoItem) -> Unit,
178+
endToStartAction: (TodoItem) -> Unit,
179+
modifier: Modifier = Modifier,
180+
content: @Composable (TodoItem) -> Unit
181+
) {
182+
val swipeToDismissState = rememberSwipeToDismissBoxState(
183+
positionalThreshold = { totalDistance -> totalDistance * 0.25f },
184+
confirmValueChange = {
185+
when (it) {
186+
SwipeToDismissBoxValue.StartToEnd -> {
187+
startToEndAction(value)
188+
// Do not dismiss this item.
189+
false
190+
}
191+
SwipeToDismissBoxValue.EndToStart -> {
192+
endToStartAction(value)
193+
true
194+
}
195+
SwipeToDismissBoxValue.Settled -> {
196+
false
197+
}
198+
}
199+
}
200+
)
201+
202+
SwipeToDismissBox(
203+
modifier = Modifier,
204+
state = swipeToDismissState,
205+
backgroundContent = {
206+
// Cross-fade the background color as the drag gesture progresses.
207+
val color by animateColorAsState(
208+
when (swipeToDismissState.targetValue) {
209+
SwipeToDismissBoxValue.Settled -> Color.LightGray
210+
SwipeToDismissBoxValue.StartToEnd ->
211+
lerp(Color.LightGray, Color.Blue, swipeToDismissState.progress)
212+
213+
214+
SwipeToDismissBoxValue.EndToStart ->
215+
lerp(Color.LightGray, Color.Red, swipeToDismissState.progress)
216+
}, label = "swipeable card item background color"
217+
)
218+
Row(
219+
modifier = Modifier
220+
.background(color)
221+
.fillMaxSize(),
222+
verticalAlignment = Alignment.CenterVertically,
223+
horizontalArrangement = Arrangement.SpaceBetween
224+
) {
225+
when (swipeToDismissState.dismissDirection) {
226+
SwipeToDismissBoxValue.StartToEnd -> {
227+
if (value.isItemDone) {
228+
Icon(
229+
imageVector = Icons.Default.CheckBox,
230+
contentDescription = "Item done",
231+
tint = Color.White,
232+
modifier = Modifier
233+
.padding(12.dp)
234+
)
235+
} else {
236+
Icon(
237+
imageVector = Icons.Default.CheckBoxOutlineBlank,
238+
contentDescription = "Item not done",
239+
tint = Color.White,
240+
modifier = Modifier
241+
.padding(12.dp)
242+
)
243+
}
244+
}
245+
246+
247+
SwipeToDismissBoxValue.EndToStart -> {
248+
Spacer(modifier = Modifier)
249+
Icon(
250+
imageVector = Icons.Default.Delete,
251+
contentDescription = "Remove item",
252+
tint = Color.White,
253+
modifier = Modifier
254+
.padding(12.dp)
255+
)
256+
}
257+
258+
259+
SwipeToDismissBoxValue.Settled -> {}
260+
}
261+
}
262+
}) {
263+
content(value)
264+
}
265+
}
266+
// [END android_compose_components_swipecarditem]
267+
268+
// [START android_compose_components_swipecarditemexample]
269+
@Preview
270+
@Composable
271+
private fun SwipeCardItemExample() {
272+
val todoItems = remember {
273+
mutableStateListOf(
274+
TodoItem(isItemDone = false, itemDescription = "Pay bills"),
275+
TodoItem(isItemDone = false, itemDescription = "Buy groceries"),
276+
TodoItem(isItemDone = false, itemDescription = "Go to gym"),
277+
TodoItem(isItemDone = false, itemDescription = "Get dinner")
278+
)
279+
}
280+
281+
LazyColumn {
282+
items(
283+
items = todoItems,
284+
key = { it.itemDescription }
285+
) { todoItem ->
286+
SwipeCardItem(
287+
value = todoItem,
288+
startToEndAction = {
289+
todoItem.isItemDone = !todoItem.isItemDone
290+
},
291+
endToStartAction = {
292+
todoItems -= todoItem
293+
}
294+
) {
295+
OutlinedCard(shape = RectangleShape) {
296+
ListItem(
297+
headlineContent = { Text(todoItem.itemDescription) },
298+
supportingContent = { Text("swipe me to update or remove.") })
299+
}
300+
}
301+
}
302+
}
303+
}
304+
// [END android_compose_components_swipecarditemexample]

0 commit comments

Comments
 (0)