We can use the snap fling behavior that would snap at the middle item but the video you provided has snapping enabled on the first visible item, there's no property of snap fling that we could change to snap at the first item.
So I have implemented something that calculates and stop at the very first item and highlights it.
I did not see that you were implementing it for tv and I created a sample for mobile :___( .
If there is any tv specific api available for this behavior you should surely go for that, if not then you can have a look at my implementation.
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun MainScreen(
modifier: Modifier
) {
val lazyRowState = rememberLazyListState()
val snappingLayout = remember(lazyRowState) { SnapLayoutInfoProvider(lazyRowState) }
val flingBehavior = rememberSnapFlingBehavior(snappingLayout)
Box(
modifier = modifier
.fillMaxSize()
) {
val firstVisibleItem by remember {
derivedStateOf {
lazyRowState.layoutInfo.visibleItemsInfo.firstOrNull()
}
}
val viewPortStartOffset by remember {
derivedStateOf {
lazyRowState.layoutInfo.viewportStartOffset
}
}
LaunchedEffect(key1 = firstVisibleItem ) {
firstVisibleItem?.let {
if(it.offset < viewPortStartOffset){
lazyRowState.animateScrollToItem(it.index)
}
}
}
LazyRow(
modifier = Modifier
.align(Alignment.Center)
.wrapContentSize(),
state = lazyRowState,
flingBehavior = flingBehavior
) {
items(50) { index ->
val isFirstItem by remember { derivedStateOf { lazyRowState.firstVisibleItemIndex == index} }
val scale by animateFloatAsState(targetValue = if(isFirstItem) 1.2f else 1f,
label = "scale animation"
)
Card(
modifier = Modifier
.padding(start = 30.dp, end = 10.dp)
.size(80.dp)
.scale(scale = scale)
.border(
if (isFirstItem) 2.dp else 0.dp,
if (isFirstItem) Color.White else Color.Transparent,
RoundedCornerShape(15.dp)
)
,
colors = CardDefaults.cardColors(Color.Blue),
shape = RoundedCornerShape(15.dp),
) {
Text(text = "$index")
}
}
}
}
}
I am actually just calculating if the offset of very first visible item goes out of the bounds of viewport and if it does then scrolling the lazy list to that item.
