androidkotlinandroid-jetpack-composebottom-sheetandroid-bottomsheetdialog

How to allow drag only on part of the SheetPeek of a BottomContent in BottomSheetScaffold?


The dragging part is possible on whole rectangle (Yellow in video) and I want it to be only allowed on the Grey icon

I can drag any part of the yellow part, whether up or down, I want to allow that behavior of dragging only on the Grey part

Left Video is the same as right video, except I made the right's sheetBackgroundColor transparent

@OptIn(ExperimentalMaterialApi::class)
@Composable
fun HomeScreen(modifier: Modifier = Modifier) {
BottomSheetScaffold(
    topBar = { AppBar() },
    sheetElevation = ZERO_DP,
    sheetPeekHeight = BOTTOM_ICON_CONTAINER_SIZE,
    sheetBackgroundColor = Color.Transparent,
    sheetContent = {
        BottomSheetContent(modifier)
    }
) {
    HomeContent()
}


@Composable
fun BottomSheetContent(
    modifier: Modifier = Modifier,
) {
    Column(
        modifier = modifier
            .fillMaxWidth()
            .fillMaxHeight(0.8f)
    ) {
        Box(
            modifier = modifier
                .padding(end = SPACING_QUADRUPLE)
                .align(Alignment.End)
                .clip(
                    RoundedCornerShape(
                        topStart = TRIPLE_CORNER_DP,
                        topEnd = TRIPLE_CORNER_DP
                    )
                )
                .size(BOTTOM_ICON_CONTAINER_SIZE)
                .background(MaterialTheme.colors.secondary)
            ,


            contentAlignment = Alignment.BottomCenter
        )
        {
            Icon(
                modifier = modifier,
                painter = painterResource(id = R.drawable.ic_qr_code),
                contentDescription = stringResource(
                    id = R.string.bottom_sheet_puller
                ),
                tint = Color.Unspecified
            )
        }

        Text(
            modifier = modifier
                .fillMaxWidth()
                .background(MaterialTheme.colors.surface)
                .padding(
                    start = SPACING_DOUBLE,
                    end = SPACING_DOUBLE,
                    bottom = SPACING_NORMAL
                ),
            text = "Scan Serial With QR",
            style = MaterialTheme.typography.h3,
        )
        Box(
            modifier = modifier
                .fillMaxSize()
                .background(color = Color.DarkGray)
        )
    }
}

Wrong Behavior: Wrong Behavior

Correct Intended Behavior: Intended Behavior


Solution

  • There must be a better solution to intercept a drag gesture and leave all of it within the green box only, but this might suffice.

    I made some changes to your BottomSheetContent, intercepting a drag gesture from a Row weighted transparent component and leaving it empty, you can try this one, and the drag gesture is only accepted by the green box,

    @Composable
    fun BottomSheetContent(
        modifier: Modifier = Modifier,
    ) {
    
        Column(
            modifier = modifier
                .fillMaxWidth()
                .fillMaxHeight(0.8f)
        ) {
            Row {
    
                Box(
                    modifier = Modifier
                        .weight(1f)
                        .draggable(
                            orientation = Orientation.Vertical,
                            state = rememberDraggableState { 
                                  Toast.makeText(context, "Non Draggable Area", Toast.LENGTH_SHORT).show()
    
                            }
                        ).fillMaxWidth().height(150.dp).background(Color.Transparent)) {
                }
    
                Box(
                    modifier = modifier
                        .padding(end = 8.dp)
                        .clip(
                            RoundedCornerShape(
                                topStart = 12.dp,
                                topEnd = 12.dp
                            )
                        )
                        .size(150.dp)
                        .background(MaterialTheme.colors.secondary),
                    contentAlignment = Alignment.BottomCenter
                ) {
                    Icon(
                        modifier = modifier,
                        imageVector = Icons.Default.Add,
                        contentDescription = "",
                    )
                }
            }
    
    
            Text(
                modifier = modifier
                    .fillMaxWidth()
                    .background(MaterialTheme.colors.surface)
                    .padding(
                        start = 8.dp,
                        end = 8.dp,
                        bottom = 4.dp
                    ),
                text = "Scan Serial With QR",
                style = MaterialTheme.typography.h3,
            )
            Box(
                modifier = modifier
                    .fillMaxSize()
                    .background(color = Color.DarkGray)
            )
        }
    }
    

    I can't show my pointer click here, but the toast shows when the left area outside of the green box is being dragged.

    enter image description here