androidandroid-jetpack-composeandroid-jetpack-compose-material3material-design-3jetpack-compose-swipe-to-dismiss

Jetpack Compose SwipeToDismissBox goes till the end of screen


I am trying to implement a swipe to dismiss feature in my app, and it works fine except for a small UI issue.

When I swipe from end to start, I want the top front container to just decrease in size rather than swiping till the end of the screen, but it's not the case. Below are screenshots of current situation and what I want to achieve:

Current

enter image description here

Desirable

enter image description here

Below is the code for the current image:

@Composable
fun SwipeToCancel(
    closeScreen: () -> Unit,
    isExpandedScreen: Boolean
) {
    val threshold = 0.5f
    val haptic = LocalHapticFeedback.current
    var state: SwipeToDismissBoxState? = null
    state = rememberSwipeToDismissBoxState(
        positionalThreshold = {
            it * threshold
        },
        confirmValueChange = {
            haptic.performHapticFeedback(HapticFeedbackType.LongPress)
            if (it == SwipeToDismissBoxValue.EndToStart && state!!.progress > threshold) {
                closeScreen()
            }
            false
        }
    )

    SwipeToDismissBox(
        state = state,
        enableDismissFromStartToEnd = false,
        enableDismissFromEndToStart = true,
        backgroundContent = {
            val containerColor by animateColorAsState(
                if (state.targetValue == SwipeToDismissBoxValue.Settled) {
                    MaterialTheme.colorScheme.inverseSurface
                } else {
                    MaterialTheme.colorScheme.error
                }, label = ""
            )
            val contentColor by animateColorAsState(
                if (state.targetValue == SwipeToDismissBoxValue.Settled) {
                    MaterialTheme.colorScheme.inverseOnSurface
                } else {
                    MaterialTheme.colorScheme.onError
                }, label = ""
            )
            Box(
                Modifier
                    .fillMaxSize()
                    .clip(MaterialTheme.shapes.medium)
                    .background(containerColor)
            ) {
                MesIcon(
                    imageVector = Icons.Outlined.CallEnd,
                    tint = contentColor,
                    modifier = Modifier
                        .align(Alignment.CenterEnd)
                        .padding(16.dp)
                )
            }
        }
    ) {

        Card(
            modifier = Modifier
                .fillMaxWidth(if (isExpandedScreen) 0.5f else 1f),
            colors = CardDefaults.outlinedCardColors(
                containerColor = MaterialTheme.colorScheme.primaryContainer
            )
        ) {
            Row(
                modifier = Modifier
                    .fillMaxWidth()
                    .height(80.dp)
                    .clip(MaterialTheme.shapes.medium)
                    .background(MaterialTheme.colorScheme.primary)
                    .padding(4.dp),
                horizontalArrangement = Arrangement.End,
                verticalAlignment = Alignment.CenterVertically
            ) {

                Text(
                    text = stringResource(id = R.string.action_slide_cancel),
                    style = MaterialTheme.typography.bodyMedium,
                    color = MaterialTheme.colorScheme.onPrimary
                )

                Spacer(modifier = Modifier.width(16.dp))

                Icon(
                    imageVector = Icons.Outlined.KeyboardDoubleArrowLeft,
                    contentDescription = stringResource(id = R.string.action_swipe_cancel),
                    tint = MaterialTheme.colorScheme.primary,
                    modifier = Modifier
                        .width(48.dp)
                        .fillMaxHeight()
                        .clip(RoundedCornerShape(12.dp))
                        .background(MaterialTheme.colorScheme.background)
                )
            }

        }

    }

}

Anyone has an idea on how to do this ?


Solution

  • Set the desired padding for the SwipeToDismissBox:

    @Composable
    fun SwipeToCancel(
        closeScreen: () -> Unit,
        isExpandedScreen: Boolean
    ) {
        ...
        SwipeToDismissBox(
            modifier = Modifier
                .padding(horizontal = 16.dp)
                .clip(RoundedCornerShape(12.dp))
            ...
        )
        ...
    }