Roberto Leinardi
Roberto Leinardi

Reputation: 14399

How can I create a SwipeToDismiss gesture using Compose and Material 3?

Question:

I'm working on an Android application using Jetpack Compose and Material 3, and I want to implement a swipe-to-dismiss gesture for a list of items. I've seen examples for older versions of Jetpack Compose and Material 2, but I'm not sure how to do this with the latest version of Compose and Material 3.

Here's what I need:

I've already set up a basic list using LazyColumn and I understand the basics of handling gestures in Compose, but I'm unsure how to specifically implement the swipe-to-dismiss functionality with the latest APIs.

Additional Information:

@Composable
fun MyList(items: List<String>) {
    LazyColumn {
        items(items) { item ->
            ListItem(
                text = { Text(item) }
            )
        }
    }
}

Upvotes: 4

Views: 1833

Answers (1)

pawchi
pawchi

Reputation: 143

This could be a basic implementation for Material3 with delete a left to right gesture.

@Composable
fun SwipeToDeleteScreen() {
    val mutableList = remember {mutableStateListOf("Ella", "Sam", "Molly", "Tom", "Greg")}

        LazyColumn(
            modifier = Modifier.fillMaxSize(),
            contentPadding = PaddingValues(all = 5.dp),
            verticalArrangement = Arrangement.spacedBy(2.dp)
        ) {
            items(mutableList) { element ->
                SwipeToDismissContainer(
                    item = element,
                    onDelete ={ mutableList.remove(element) }
                ) {
                    Row(modifier = Modifier.fillMaxSize().padding(8.dp)) {
                        Text(text = element)
                    }
                }
            }
        }
}

@Composable
fun SwipeToDismissContainer(
    item: String,
    onDelete: (String) -> Unit,
    content: @Composable (String) -> Unit
) {
    val dismissState = rememberSwipeToDismissBoxState(
        confirmValueChange = { newValue ->
            if(newValue == SwipeToDismissBoxValue.StartToEnd){
                onDelete(item)
                true
            } else {
                false
            }
        }
    )

    SwipeToDismissBox(
        state = dismissState,
        modifier = Modifier,
        backgroundContent = {
            if (dismissState.dismissDirection.name == SwipeToDismissBoxValue.StartToEnd.name) {
                Row(modifier = Modifier.fillMaxSize().background(Color.Red),
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    Icon(Icons.Default.Delete, contentDescription = "delete")
                }
            }
        },
        enableDismissFromEndToStart = false,
        content = {content(item)}
    )
}

Upvotes: 0

Related Questions