From bdb7e62d76e5d6e2720b9858cf2b7d27fe4bed38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E1=84=8C=E1=85=A5=E1=86=BC=E1=84=89=E1=85=AE=E1=84=8E?= =?UTF-8?q?=E1=85=A5=E1=86=AB?= Date: Tue, 29 Oct 2024 16:50:53 +0900 Subject: [PATCH] =?UTF-8?q?[MP-5164]=20tabBarChip01=20=ED=81=B4=EB=A6=AD?= =?UTF-8?q?=EC=8B=9C=20offset=20=EC=9D=B4=EC=9A=A9=ED=95=B4=EC=84=9C=20?= =?UTF-8?q?=EC=9E=90=EC=97=B0=EC=8A=A4=EB=9F=BD=EA=B2=8C=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99=EB=90=98=EA=B2=8C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../deali/designsystem/component/TabBar.kt | 52 +++++++++++++++++-- .../sample/ui/screen/TabBarScreen.kt | 20 +++++-- 2 files changed, 64 insertions(+), 8 deletions(-) diff --git a/designsystem/src/main/java/net/deali/designsystem/component/TabBar.kt b/designsystem/src/main/java/net/deali/designsystem/component/TabBar.kt index f7d23f4..5d3ea57 100644 --- a/designsystem/src/main/java/net/deali/designsystem/component/TabBar.kt +++ b/designsystem/src/main/java/net/deali/designsystem/component/TabBar.kt @@ -4,6 +4,7 @@ package net.deali.designsystem.component import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background +import androidx.compose.foundation.gestures.animateScrollBy import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxWidth @@ -17,9 +18,18 @@ import androidx.compose.foundation.pager.PagerScope import androidx.compose.foundation.pager.PagerState import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableFloatStateOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.layout.onGloballyPositioned +import androidx.compose.ui.layout.positionInParent +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import kotlinx.coroutines.CoroutineScope @@ -206,29 +216,63 @@ fun tabBarChip01( scope: CoroutineScope = rememberCoroutineScope(), onSelectTab: (index: Int) -> Unit, ) { + val density = LocalDensity.current + + val rowContentPadding = 12.dp + var rowWidth by remember { mutableFloatStateOf(0f) } + val rowContentPaddingPx = with(density) { rowContentPadding.toPx() } + var scrollingOffset by remember { mutableStateOf(null) } + LazyRow( modifier = modifier .fillMaxWidth() .height(56.dp) - .background(DealiColor.primary04), + .background(DealiColor.primary04) + .onGloballyPositioned { coordinates -> + rowWidth = coordinates.size.width.toFloat() + }, state = state, - contentPadding = PaddingValues(horizontal = 12.dp) + contentPadding = PaddingValues(horizontal = rowContentPadding) ) { itemsIndexed(tabTitles) { index, title -> + var chipWidth by remember { mutableFloatStateOf(0f) } + var chipOffset by remember { mutableFloatStateOf(0f) } + chipFilledSmall02( modifier = Modifier - .padding(horizontal = 4.dp, vertical = 12.dp), + .padding(horizontal = 4.dp, vertical = 12.dp) + .onGloballyPositioned { coordinates -> + chipWidth = coordinates.size.width.toFloat() + chipOffset = coordinates.positionInParent().x + }, text = title, selected = index == currentIndex, onClick = { scope.launch { onSelectTab(index) - state.animateScrollToItem(index) + + when { + // 왼쪽 범위를 벗어난 경우 + chipOffset < rowContentPaddingPx -> { + scrollingOffset = chipOffset - rowContentPaddingPx + } + + // 오른쪽 범위를 벗어난 경우 + (chipOffset + chipWidth) > rowWidth - rowContentPaddingPx -> { + scrollingOffset = (chipOffset + chipWidth) - rowWidth + rowContentPaddingPx + } + } } }, ) } } + + LaunchedEffect(scrollingOffset) { + scrollingOffset?.let { + state.animateScrollBy(it) + } + } } /** diff --git a/sample/src/main/java/net/deali/designsystem/sample/ui/screen/TabBarScreen.kt b/sample/src/main/java/net/deali/designsystem/sample/ui/screen/TabBarScreen.kt index cb5e6ad..77f4201 100644 --- a/sample/src/main/java/net/deali/designsystem/sample/ui/screen/TabBarScreen.kt +++ b/sample/src/main/java/net/deali/designsystem/sample/ui/screen/TabBarScreen.kt @@ -45,7 +45,19 @@ fun TabBarScreen( Tab("Title1", true), Tab("Title2", false), ) - val subTitles = listOf("Sub0", "Sub1", "Sub2", "Sub3", "Sub4") + + val tabsScrollable = listOf( + Tab("Title0", false), + Tab("Title1", true), + Tab("Title2", false), + Tab("Title3", false), + Tab("Title4", false), + Tab("Title5", false), + Tab("Title6", false), + Tab("Title7", false), + ) + + val subTitles = listOf("Sub0", "Sub1", "Sub2", "Sub3", "Sub4", "Sub5", "Sub6", "Sub7", "Sub8", "Sub9") val scrollState = rememberScrollState() Column( @@ -91,7 +103,7 @@ fun TabBarScreen( ) tabBarSlider01Layout( - tabs = tabs, + tabs = tabsScrollable, onSelectTab = {}, userSwipeEnabled = true, ) { page -> @@ -120,7 +132,7 @@ fun TabBarScreen( ) tabBarSlider02Layout( - tabs = tabs, + tabs = tabsScrollable, onSelectTab = {}, userSwipeEnabled = false, ) { page -> @@ -149,7 +161,7 @@ fun TabBarScreen( ) tabBarSlider02Layout( - tabs = tabs, + tabs = tabsScrollable, onSelectTab = {}, userSwipeEnabled = true, ) { page ->