Skip to content

Commit 195bd61

Browse files
authored
Adding top bar multi selection examples (#387)
* Adding top bar multi selection examples * Apply Spotless * Remember some vals --------- Co-authored-by: jakeroseman <[email protected]>
1 parent 5ccd4a8 commit 195bd61

File tree

1 file changed

+167
-0
lines changed
  • compose/snippets/src/main/java/com/example/compose/snippets/components

1 file changed

+167
-0
lines changed

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

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,17 @@
1616

1717
package com.example.compose.snippets.components
1818

19+
import androidx.compose.foundation.ExperimentalFoundationApi
20+
import androidx.compose.foundation.combinedClickable
21+
import androidx.compose.foundation.interaction.MutableInteractionSource
1922
import androidx.compose.foundation.layout.Arrangement
23+
import androidx.compose.foundation.layout.Box
2024
import androidx.compose.foundation.layout.Column
2125
import androidx.compose.foundation.layout.PaddingValues
2226
import androidx.compose.foundation.layout.fillMaxSize
2327
import androidx.compose.foundation.layout.padding
2428
import androidx.compose.foundation.lazy.LazyColumn
29+
import androidx.compose.foundation.lazy.itemsIndexed
2530
import androidx.compose.material.icons.Icons
2631
import androidx.compose.material.icons.automirrored.filled.ArrowBack
2732
import androidx.compose.material.icons.filled.Add
@@ -30,6 +35,7 @@ import androidx.compose.material.icons.filled.Edit
3035
import androidx.compose.material.icons.filled.Image
3136
import androidx.compose.material.icons.filled.Menu
3237
import androidx.compose.material.icons.filled.Mic
38+
import androidx.compose.material.icons.filled.Share
3339
import androidx.compose.material3.BottomAppBar
3440
import androidx.compose.material3.BottomAppBarDefaults
3541
import androidx.compose.material3.Button
@@ -40,6 +46,7 @@ import androidx.compose.material3.FloatingActionButtonDefaults
4046
import androidx.compose.material3.Icon
4147
import androidx.compose.material3.IconButton
4248
import androidx.compose.material3.LargeTopAppBar
49+
import androidx.compose.material3.ListItem
4350
import androidx.compose.material3.MaterialTheme
4451
import androidx.compose.material3.MediumTopAppBar
4552
import androidx.compose.material3.Scaffold
@@ -52,6 +59,7 @@ import androidx.compose.runtime.Composable
5259
import androidx.compose.runtime.getValue
5360
import androidx.compose.runtime.mutableStateOf
5461
import androidx.compose.runtime.remember
62+
import androidx.compose.runtime.saveable.rememberSaveable
5563
import androidx.compose.runtime.setValue
5664
import androidx.compose.ui.Modifier
5765
import androidx.compose.ui.input.nestedscroll.nestedScroll
@@ -76,13 +84,15 @@ fun AppBarExamples(
7684
"topBarMedium" -> MediumTopAppBarExample()
7785
"topBarLarge" -> LargeTopAppBarExample()
7886
"topBarNavigation" -> TopBarNavigationExample { navigateBack() }
87+
"multiSelection" -> AppBarMultiSelectionExample()
7988
else -> AppBarOptions(
8089
toBottom = { selection = "bottomBar" },
8190
toTopBarSmall = { selection = "topBar" },
8291
toTopBarCenter = { selection = "topBarCenter" },
8392
toTopBarMedium = { selection = "topBarMedium" },
8493
toTopBarLarge = { selection = "topBarLarge" },
8594
toTopBarNavigation = { selection = "topBarNavigation" },
95+
toMultiSelection = { selection = "multiSelection" },
8696
)
8797
}
8898
}
@@ -96,6 +106,7 @@ fun AppBarOptions(
96106
toTopBarMedium: () -> Unit,
97107
toTopBarLarge: () -> Unit,
98108
toTopBarNavigation: () -> Unit,
109+
toMultiSelection: () -> Unit,
99110
) {
100111
Column() {
101112
Button({ toBottom() }) {
@@ -116,6 +127,9 @@ fun AppBarOptions(
116127
Button({ toTopBarNavigation() }) {
117128
Text("Top bar navigation example")
118129
}
130+
Button({ toMultiSelection() }) {
131+
Text("Top bar with multi selection list")
132+
}
119133
}
120134
}
121135

@@ -382,3 +396,156 @@ fun ScrollContent(innerPadding: PaddingValues) {
382396
}
383397
}
384398
}
399+
400+
@OptIn(ExperimentalMaterial3Api::class)
401+
// [START android_compose_components_appbarselectionactions]
402+
@Composable
403+
fun AppBarSelectionActions(
404+
selectedItems: Set<Int>,
405+
modifier: Modifier = Modifier,
406+
) {
407+
val hasSelection = selectedItems.isNotEmpty()
408+
val topBarText = if (hasSelection) {
409+
"Selected ${selectedItems.size} items"
410+
} else {
411+
"List of items"
412+
}
413+
414+
TopAppBar(
415+
title = {
416+
Text(topBarText)
417+
},
418+
colors = TopAppBarDefaults.topAppBarColors(
419+
containerColor = MaterialTheme.colorScheme.primaryContainer,
420+
titleContentColor = MaterialTheme.colorScheme.primary,
421+
),
422+
actions = {
423+
if (hasSelection) {
424+
IconButton(onClick = {
425+
/* click action */
426+
}) {
427+
Icon(
428+
imageVector = Icons.Filled.Share,
429+
contentDescription = "Share items"
430+
)
431+
}
432+
}
433+
},
434+
)
435+
}
436+
// [END android_compose_components_appbarselectionactions]
437+
438+
@Preview
439+
@Composable
440+
private fun AppBarSelectionActionsPreview() {
441+
val selectedItems = setOf(1, 2, 3)
442+
443+
AppBarSelectionActions(selectedItems)
444+
}
445+
446+
@OptIn(ExperimentalFoundationApi::class)
447+
@Preview
448+
// [START android_compose_components_appbarmultiselectionexample]
449+
@Composable
450+
private fun AppBarMultiSelectionExample(
451+
modifier: Modifier = Modifier,
452+
) {
453+
val listItems by remember { mutableStateOf(listOf(1, 2, 3, 4, 5, 6)) }
454+
var selectedItems by rememberSaveable { mutableStateOf(setOf<Int>()) }
455+
456+
Scaffold(
457+
topBar = { AppBarSelectionActions(selectedItems) }
458+
) { innerPadding ->
459+
LazyColumn(contentPadding = innerPadding) {
460+
itemsIndexed(listItems) { _, index ->
461+
val isItemSelected = selectedItems.contains(index)
462+
ListItemSelectable(
463+
selected = isItemSelected,
464+
Modifier
465+
.combinedClickable(
466+
interactionSource = remember { MutableInteractionSource() },
467+
indication = null,
468+
onClick = {
469+
/* click action */
470+
},
471+
onLongClick = {
472+
if (isItemSelected) selectedItems -= index else selectedItems += index
473+
}
474+
)
475+
)
476+
}
477+
}
478+
}
479+
}
480+
// [END android_compose_components_appbarmultiselectionexample]
481+
482+
// [START android_compose_components_listitemselectable]
483+
@Composable
484+
fun ListItemSelectable(
485+
selected: Boolean,
486+
modifier: Modifier = Modifier
487+
) {
488+
Box(modifier = modifier) {
489+
ListItem(
490+
headlineContent = { Text("Long press to select or deselect item") },
491+
leadingContent = {
492+
if (selected) {
493+
Icon(
494+
Icons.Filled.Check,
495+
contentDescription = "Localized description",
496+
)
497+
}
498+
}
499+
)
500+
}
501+
}
502+
// [END android_compose_components_listitemselectable]
503+
504+
@Preview
505+
@Composable
506+
private fun ListItemSelectablePreview() {
507+
ListItemSelectable(true)
508+
}
509+
510+
@OptIn(ExperimentalFoundationApi::class)
511+
// [START android_compose_components_lazylistmultiselection
512+
@Composable
513+
fun LazyListMultiSelection(
514+
listItems: List<Int>,
515+
modifier: Modifier = Modifier,
516+
contentPadding: PaddingValues = PaddingValues(0.dp),
517+
) {
518+
var selectedItems by rememberSaveable { mutableStateOf(setOf<Int>()) }
519+
520+
LazyColumn(contentPadding = contentPadding) {
521+
itemsIndexed(listItems) { _, index ->
522+
val selected = selectedItems.contains(index)
523+
ListItemSelectable(
524+
selected = selected,
525+
Modifier
526+
.combinedClickable(
527+
interactionSource = remember { MutableInteractionSource() },
528+
indication = null,
529+
onClick = {
530+
/* click action */
531+
},
532+
onLongClick = {
533+
if (selected) selectedItems -= index else selectedItems += index
534+
}
535+
)
536+
)
537+
}
538+
}
539+
}
540+
// [END android_compose_components_lazylistmultiselection
541+
542+
@Preview
543+
@Composable
544+
private fun LazyListMultiSelectionPreview() {
545+
val listItems = listOf(1, 2, 3)
546+
547+
LazyListMultiSelection(
548+
listItems,
549+
modifier = Modifier
550+
)
551+
}

0 commit comments

Comments
 (0)