카테고리 없음

[Android] Compose - Hidden Button이 있는 Button 만들기

Jun.LEE 2024. 8. 1. 16:39

드래그를 하여 숨겨진 버튼이 나타나도록 하는 Composable 함수를 만들어 보려고 한다.

 

위와 같이 Box Composable을 하나 주고 Child로 Button들을 배치할 Row,

그 위에 Drag에 의해 사이즈를 조정할 Box를 하나 배치하려고 한다.

 

Drag를 통하여 초록 Box의 사이즈를 바꾸는 것으로 뒤에 배치된 Button들이 보이도록 하는 것이 목표이다.

 

먼저, 위 연산을 진행하려면 각 크기를 알아야 하므로 다음과 같이 작성했다.

@Composable
fun FolderButton(
    hiddenButtons: @Composable RowScope.() -> Unit,
) {
    var hiddenButtonGroupWidth by remember { mutableIntStateOf(0) }
    var outerSize by remember { mutableStateOf(IntSize.Zero) }
    var innerWidth by remember { mutableIntStateOf(0) }

    Box(
        modifier = modifier
            .onSizeChanged {
                outerSize = it
                innerWidth = it.width
            }
    ) {
        Row(
            modifier = Modifier
                .align(Alignment.CenterEnd)
                .onSizeChanged { 
                	hiddenButtonGroupWidth = it.width 
                }
        ) { 
            hiddenButtons() 
        }
    }

 

위 값들을 통하여 이제 이 함수에서 가장 핵심적인 연산을 해야 한다.

드래그했을 때 innerWidth state를 변경해 주는 것으로 가장 바깥 Box의 크기를 조정해야 한다.

Box(
    modifier = Modifier
        .width(pixelToDp(innerWidth))
        .height(pixelToDp(outerSize.height))
        .background(innerColor)
        .pointerInput(Unit) {
            detectHorizontalDragGestures(
                onHorizontalDrag = { change, dragAmount ->
                    innerWidth = (innerWidth + dragAmount.toInt()).coerceIn(
                        minimumValue = outerSize.width - hiddenButtonGroupWidth,
                        maximumValue = outerSize.width
                    )
                    change.consume()
                },
                onDragEnd = {
                    if (innerWidth < outerSize.width - hiddenButtonGroupWidth / 2) {
                        innerWidth = outerSize.width - hiddenButtonGroupWidth
                    } else {
                        innerWidth = outerSize.width
                    }
                }
            )
        }
) {
    Text(
        modifier = Modifier
            .align(Alignment.Center)
            .padding(textPadding),
        text = text,
        maxLines = 1,
        overflow = TextOverflow.Ellipsis,
        color = MaterialTheme.colorScheme.onPrimaryContainer,
        fontSize = fontSize
    )
}

 

@Composable
fun pixelToDp(px: Int): Dp {
    val density = LocalDensity.current.density
    return (px / density).dp
}

 

드래그한 양 만큼 크기가 Box의 width의 크기를 변경하도록 작성하였고,

Button들을 포함한 Row의 범위 내에서 처리 되도록 의도했다.

 

마지막으로, Drag를 마치면 Row의 절반을 기준으로 크기가 Button들을 감추거나 보이는 

적당한 사이즈로 변경되도록 의도하였다.