Skip to content

Instantly share code, notes, and snippets.

@cathandnya
Created March 13, 2023 00:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cathandnya/82e57d77930ee53a4bd02c9ab9b842c8 to your computer and use it in GitHub Desktop.
Save cathandnya/82e57d77930ee53a4bd02c9ab9b842c8 to your computer and use it in GitHub Desktop.
LazyRowPager
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun LazyRowPager(
modifier: Modifier = Modifier,
listState: LazyListState = rememberLazyListState(),
onChangeCurrentIndex: ((Int) -> Unit)? = null,
contentPadding: Dp = 0.dp,
itemSpacing: Dp = 0.dp,
content: LazyListScope.(Dp) -> Unit,
) {
val density = LocalDensity.current
val flingBehavior = rememberSnapFlingBehavior(listState)
var width by remember { mutableStateOf(0.dp) }
LaunchedEffect(listState) {
snapshotFlow { listState.layoutInfo }
.collect { info ->
onChangeCurrentIndex?.let { handler ->
info.visibleItemsInfo.firstOrNull {
with(density) { it.offset.toDp() } + width / 2 >= 0.dp
}?.let { i ->
handler(i.index)
}
}
}
}
LazyRow(
state = listState,
flingBehavior = flingBehavior,
modifier = modifier
.onGloballyPositioned {
width = with(density) { it.size.width.toDp() }
},
contentPadding = PaddingValues(horizontal = contentPadding),
horizontalArrangement = Arrangement.spacedBy(itemSpacing)
) {
val w = width - contentPadding * 2
if (w > 0.dp) {
content(w)
}
}
}
@Preview
@Composable
fun LazyRowPager_Preview() {
val list = listOf(
Pair("1", Color.Red),
Pair("2", Color.Green),
Pair("3", Color.Blue),
Pair("4", Color.Yellow),
)
var currentIndex by remember { mutableStateOf(0) }
Column(
modifier = Modifier
.background(Color.White)
.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
) {
LazyRowPager(
modifier = Modifier
.fillMaxWidth()
.height(200.dp),
contentPadding = 20.dp,
itemSpacing = 10.dp,
onChangeCurrentIndex = {
currentIndex = it
}
) { width ->
items(list) { item ->
Box(
modifier = Modifier
.background(item.second)
.width(width)
.height(200.dp),
contentAlignment = Alignment.Center,
) {
Text(
item.first,
)
}
}
}
Spacer(modifier = Modifier.height(20.dp))
Text(
"currentIndex: " + (currentIndex + 1).toString(),
fontSize = 20.sp,
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment