안드로이드/개발관련(Kotlin)

Gravity start TabRow (Compose)

닉네임못짓는사람 2024. 7. 30. 21:05
반응형
@Composable
fun<T> CustomTabRow(
    selectedTabIndex: Int,
    modifier: Modifier = Modifier,
    containerColor: Color = colorResource(id = R.color.transparent),
    startPadding: Dp = 0.dp,
    contentPadding: Dp = 0.dp,
    items: List<T>,
    content: @Composable (index: Int, item: T, modifier: Modifier) -> Unit
) {
    Box(
        modifier = modifier
            .fillMaxWidth()
            .background(containerColor)
    ) {
        val density = LocalDensity.current
        val positions = remember(key1 = items) {
            mutableStateListOf<Pair<Dp, Dp>>().apply { addAll(items.map { Pair(0.dp, 0.dp) }) }
        }
        val indicatorOffset = animateDpAsState(targetValue = positions[selectedTabIndex].first)
        val indicatorWidth = animateDpAsState(targetValue = positions[selectedTabIndex].second)

        LazyRow(
            verticalAlignment = Alignment.CenterVertically,
            modifier = Modifier
                .fillMaxHeight()
        ) {
            item { Spacer(modifier = Modifier.width(startPadding)) }
            itemsIndexed(items) { index, item ->
                content(index, item, Modifier
                    .onGloballyPositioned {
                        with(density) {
                            positions[index] = Pair(it.positionInParent().x.toDp(), it.size.width.dp.value.toDp())
                        }
                    }
                )
                if (index < items.lastIndex) Spacer(modifier = Modifier.width(contentPadding))
            }
        }
        Box(
            modifier = Modifier
                .width(indicatorWidth.value)
                .height(4.dp)
                .offset(x = indicatorOffset.value)
                .background(Color.Black)
                .align(Alignment.BottomStart)
        )
    }
}

 

Compose에서 기본적으로 제공하는 TabRow는 아이템들이 동일한 크기로 꽉 차게 배치되어서

start에서부터 하위 composable크기 만큼만 배치되는 tabRow 작성

반응형