我正在尝试实现一件简单的事情:我有一个 ScrollableTabRow 和一个 HorizontalPager ,我想让 ScrollableTabRow 的指示器在我向左或向右拖动 HorizontalPager 时移动。
现在,只有当我更改页面时它才会移动。
它可以使用 XML 开箱即用,但现在我觉得我必须这样做,但我不知道做什么。
代码:
ScrollableTabRow(selectedTabIndex = selectedTabIndex.value,
indicator = { positions ->
TabRowDefaults.SecondaryIndicator(
Modifier.tabIndicatorOffset(positions[pagerState.currentPage])
)
},
modifier = Modifier.fillMaxWidth(),
containerColor = getTopBarColor()) {
data.forEachIndexed { index, _ ->
Tab(
text = { Text(tabTitle, maxLines = 1) },
selected = selectedTabIndex.value == index,
onClick = {
scope.launch {
pagerState.animateScrollToPage(index)
}
}
)
}
}
HorizontalPager(state = pagerState, modifier = Modifier
.fillMaxWidth()
.weight(1f)) { page ->
// Show the page
}
....
试试这个
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TabIndicatorScope.SynchronizedIndicator(
selectedTabIndex: Int,
pagerOffset: Float,
modifier: Modifier = Modifier,
width: Dp = 24.dp,
height: Dp = 3.dp,
color: Color = Color.Unspecified,
shape: Shape = RectangleShape
) {
Spacer(
modifier.tabIndicatorLayout { measurable: Measurable,
constraints: Constraints,
tabPositions: List<TabPosition> ->
val floatingIndex = selectedTabIndex + pagerOffset
val startTab =
tabPositions[floatingIndex
.toInt()
.coerceIn(0, tabPositions.lastIndex)]
val endTab =
tabPositions[(floatingIndex.toInt() + 1).coerceIn(0, tabPositions.lastIndex)]
val startCenter = (startTab.left + startTab.right) / 2
val endCenter = (endTab.left + endTab.right) / 2
val startIndicatorPosition = startCenter - startTab.contentWidth / 2
val endIndicatorPosition = endCenter - endTab.contentWidth / 2
val startIndicatorEndPosition = startCenter + startTab.contentWidth / 2
val endIndicatorEndPosition = endCenter + endTab.contentWidth / 2
val progress = floatingIndex - floatingIndex.toInt()
val indicatorStart =
startIndicatorPosition + (endIndicatorPosition - startIndicatorPosition) * progress
val indicatorEnd =
startIndicatorEndPosition + (endIndicatorEndPosition - startIndicatorEndPosition) * progress
val placeable = measurable.measure(
constraints.copy(
maxWidth = (indicatorEnd - indicatorStart).roundToPx(),
minWidth = (indicatorEnd - indicatorStart).roundToPx()
)
)
layout(constraints.maxWidth, placeable.height) {
placeable.place(indicatorStart.roundToPx(), 0)
}
}
.requiredHeight(height)
.requiredWidth(width)
.background(color = color, shape = shape)
)
}
然后在你的代码中
val pager = rememberPagerState(initialPage = 0) { 4 }
PrimaryTabRow(
selectedTabIndex = pager.currentPage,
indicator = {
SynchronizedIndicator(
selectedTabIndex = pager.currentPage,
pagerOffset = pager.currentPageOffsetFraction,
width = Dp.Unspecified,
height = 5.dp,
color = Color.White,
shape = RoundedCornerShape(topStart = 3.dp, topEnd = 3.dp)
)
}
) {
//Your tabs
}
//HorizontalPager
有关指标的更多信息位于此处