Skip to content

Commit 87edd32

Browse files
committed
Snippet for animated sorted list with add/remove buttons.
1 parent 90b8500 commit 87edd32

File tree

1 file changed

+154
-0
lines changed

1 file changed

+154
-0
lines changed
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
package com.example.compose.snippets.lists
2+
3+
import androidx.compose.foundation.layout.Arrangement
4+
import androidx.compose.foundation.layout.Column
5+
import androidx.compose.foundation.layout.Row
6+
import androidx.compose.foundation.layout.Spacer
7+
import androidx.compose.foundation.layout.fillMaxSize
8+
import androidx.compose.foundation.layout.fillMaxWidth
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.material3.Button
13+
import androidx.compose.material3.ListItem
14+
import androidx.compose.material3.Scaffold
15+
import androidx.compose.material3.SegmentedButton
16+
import androidx.compose.material3.SegmentedButtonDefaults
17+
import androidx.compose.material3.SingleChoiceSegmentedButtonRow
18+
import androidx.compose.material3.Text
19+
import androidx.compose.runtime.Composable
20+
import androidx.compose.runtime.MutableState
21+
import androidx.compose.runtime.getValue
22+
import androidx.compose.runtime.mutableIntStateOf
23+
import androidx.compose.runtime.mutableStateOf
24+
import androidx.compose.runtime.remember
25+
import androidx.compose.runtime.setValue
26+
import androidx.compose.ui.Modifier
27+
import androidx.compose.ui.tooling.preview.Preview
28+
import androidx.compose.ui.unit.dp
29+
30+
// [START android_compose_layouts_list_listanimateditems]
31+
@Composable
32+
fun ListAnimatedItems(
33+
items: List<String>,
34+
modifier: Modifier = Modifier
35+
) {
36+
LazyColumn {
37+
items(items, key = { it }) {
38+
ListItem(
39+
headlineContent = { Text(it) },
40+
modifier = Modifier
41+
.animateItem()
42+
.fillParentMaxWidth()
43+
.padding(horizontal = 8.dp, vertical = 0.dp),
44+
)
45+
}
46+
}
47+
}
48+
// [END android_compose_layouts_list_listanimateditems]
49+
50+
// [START android_compose_layouts_list_listanimateditemsexample]
51+
@Composable
52+
private fun ListAnimatedItemsExample(data: List<String>) {
53+
Scaffold { paddingValues ->
54+
Column(
55+
modifier = Modifier
56+
.padding(paddingValues)
57+
.fillMaxSize()
58+
) {
59+
val displayedItems = remember { mutableStateOf(data) }
60+
61+
// Buttons that change the value of displayedItems.
62+
AddRemoveButtons(data, displayedItems)
63+
OrderButtons(data, displayedItems)
64+
65+
// List that displays the values of displayedItems.
66+
ListAnimatedItems(displayedItems.value)
67+
}
68+
}
69+
}
70+
// [END android_compose_layouts_list_listanimateditemsexample]
71+
72+
// [START android_compose_layouts_list_addremovebuttons]
73+
@Composable
74+
private fun AddRemoveButtons(
75+
data: List<String>,
76+
displayedItems: MutableState<List<String>>
77+
) {
78+
Row(
79+
modifier = Modifier.fillMaxWidth(),
80+
horizontalArrangement = Arrangement.Center
81+
) {
82+
Button(
83+
enabled = displayedItems.value.size < data.size,
84+
onClick = {
85+
// Avoid duplicate items
86+
val remainingItems = data.filter { it !in displayedItems.value }
87+
if (remainingItems.isNotEmpty()) displayedItems.value += remainingItems.first()
88+
},
89+
) {
90+
Text("Add Item")
91+
}
92+
Spacer(modifier = Modifier.padding(25.dp))
93+
Button(
94+
enabled = displayedItems.value.isNotEmpty(),
95+
onClick = {
96+
displayedItems.value =
97+
displayedItems.value.toMutableList().dropLast(1).toList()
98+
},
99+
) {
100+
Text("Delete Item")
101+
}
102+
}
103+
}
104+
// [END android_compose_layouts_list_addremovebuttons]
105+
106+
// [START android_compose_layouts_list_orderbuttons]
107+
@Composable
108+
private fun OrderButtons(
109+
data: List<String>,
110+
displayedItems: MutableState<List<String>>
111+
) {
112+
val sortAlpha = Comparator { str: String, str2: String -> str.compareTo(str2) }
113+
val sortLength = Comparator { str1: String, str2: String -> str1.length - str2.length }
114+
115+
Row(
116+
modifier = Modifier.fillMaxWidth(),
117+
horizontalArrangement = Arrangement.Center
118+
) {
119+
var selectedIndex by remember { mutableIntStateOf(0) }
120+
val options = listOf("Reset", "Alphabetical", "Length")
121+
122+
SingleChoiceSegmentedButtonRow {
123+
options.forEachIndexed { index, label ->
124+
SegmentedButton(
125+
shape = SegmentedButtonDefaults.itemShape(
126+
index = index,
127+
count = options.size
128+
),
129+
onClick = {
130+
selectedIndex = index
131+
when (options[selectedIndex]) {
132+
"Reset" -> displayedItems.value = data
133+
"Alphabetical" -> displayedItems.value =
134+
displayedItems.value.sortedWith(sortAlpha)
135+
"Length" -> displayedItems.value =
136+
displayedItems.value.sortedWith(sortLength)
137+
}
138+
},
139+
selected = index == selectedIndex
140+
) {
141+
Text(label)
142+
}
143+
}
144+
}
145+
}
146+
}
147+
// [END android_compose_layouts_list_orderbuttons]
148+
149+
@Preview
150+
@Composable
151+
fun ListAnimatingItemsExamplePreview(){
152+
val list = listOf("One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten")
153+
ListAnimatedItemsExample(list)
154+
}

0 commit comments

Comments
 (0)