如何让Jetpack Compose的ScrollableTabRow内容超出屏幕宽度
需求:实现可超出屏幕宽度的ScrollableTabRow
预期效果
- 完全向左滚动时:

- 滚动到中间位置时:

- 完全向右滚动时:

现有问题:官方ScrollableTabRow无法满足需求
官方Material组件ScrollableTabRow会填充屏幕剩余宽度,而非完全包裹内容,无法实现上述预期效果,实际表现如下:
- 完全向左滚动时:

- 完全向右滚动时:

当前使用ScrollableTabRow的代码
注:1.unit 等价于 4.dp
Row { HorizontalSpacer(width = 4.unit) ScrollableTabRow( modifier = Modifier.clip(CircleShape).wrapContentSize(), selectedTabIndex = pagerState.currentPage, indicator = { tabPositions -> SpecsheetTabIndicator(tabPositions = tabPositions, pagerState = pagerState) }, edgePadding = 0.dp, divider = {}, containerColor = MaterialTheme.colorScheme.primaryContainer, ) { for ((index, tab) in tabs.withIndex()) { val textColor by animateColorAsState( targetValue = when (pagerState.currentPage) { index -> MaterialTheme.colorScheme.onPrimary else -> MaterialTheme.colorScheme.onPrimaryContainer }, ) Tab( modifier = Modifier .zIndex(6f) .clip(CircleShape), selected = pagerState.currentPage == index, onClick = { coroutineScope.launch { pagerState.animateScrollToPage(index) } }, text = { Text( text = tab.text(), color = textColor, ) }, ) } } HorizontalSpacer(width = 4.unit) }
嵌套滚动的问题
外层Row并未实现滚动,尝试为其添加horizontalScroll修饰符时,应用会因未处理嵌套滚动而崩溃。
替代方案:普通Row实现视觉效果,但缺失核心功能
曾用普通Row实现了预期的视觉效果,但无法复现ScrollableTabRow的诸多内置功能,比如指示器的正确渲染、选中标签不可见时自动滚动到该标签等。代码如下:
Row( modifier = Modifier.horizontalScroll(scrollState), ) { HorizontalSpacer(width = 4.unit) Row( modifier = Modifier .clip(CircleShape) .background(MaterialTheme.colorScheme.primaryContainer) ) { for ((index, tab) in tabs.withIndex()) { val containerColor by animateColorAsState( targetValue = when (pagerState.currentPage) { index -> MaterialTheme.colorScheme.primary else -> Color.Transparent }, ) val textColor by animateColorAsState( targetValue = when (pagerState.currentPage) { index -> MaterialTheme.colorScheme.onPrimary else -> MaterialTheme.colorScheme.onPrimaryContainer }, ) Surface( modifier = Modifier.clip(CircleShape), color = containerColor, ) { Tab( modifier = Modifier .zIndex(6f) .clip(CircleShape) .defaultMinSize(minWidth = 24.unit), selected = pagerState.currentPage == index, onClick = { coroutineScope.launch { pagerState.animateScrollToPage(index) } }, text = { Text( text = tab.text(), color = textColor, ) }, ) } } } HorizontalSpacer(width = 4.unit) }
希望能得到帮助,实现兼具视觉效果和ScrollableTabRow核心功能的解决方案。
内容的提问来源于stack exchange,提问作者hamthenormal
相关产品推荐
相关产品推荐

