Reputation: 858
I want to programmatically change which tab is selected as the user scrolls past each "see more" item in the list below. How would I best accomplish this?
Upvotes: 27
Views: 31114
Reputation: 1687
Just create a NestedScrollConnection
and assign it to parent view nestedScroll
modifier:
val nestedScrollConnection = remember {
object : NestedScrollConnection {
override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
val delta = available.y
// called when you scroll the content
return Offset.Zero
}
}
}
Assign it to LazyColumn
or to its parent composed view:
Modifier.nestedScroll(nestedScrollConnection)
Exemple:
LazyColumn(
...
modifier = Modifier.nestedScroll(nestedScrollConnection)
) {
items(...) {
Text("Your text...")
}
}
Upvotes: 29
Reputation: 1377
As Ryan M writes, you can use LazyListState.firstVisibleItemIndex
. The magic of Compose is that you can just use it in an if
statement and Compose will do the work. Look at the following example, which displays a different text based on the first visible item. Similarly, you can select a different tab based on the first visible item.
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val listState = rememberLazyListState()
Column {
Text(if (listState.firstVisibleItemIndex < 100) "< 100" else ">= 100")
LazyColumn(state = listState) {
items(1000) {
Text(
text = "$it",
modifier = Modifier.fillMaxWidth(),
)
}
}
}
}
}
}
Upvotes: 19
Reputation: 20119
You can use the LazyListState.firstVisibleItemIndex
property (obtained via rememberLazyListState
and set as the state
parameter to LazyColumn
) and set the current tab based on that.
Reading that property is considered a model read in Compose, so it will trigger a recomposition whenever the first visible item changes.
If you instead want to do something more complex based on more than just the first visible item, you can use LazyListState.layoutInfo
to get information about all visible items and their locations, rather than just the first.
Upvotes: 9