Jetpack Compose LazyColumn 滚动侦听器

Cha*_*son 5 android list android-jetpack-compose

我想以编程方式更改选择哪个选项卡,因为用户滚动经过下面列表中的每个“查看更多”项目。我将如何最好地完成此操作?

在此处输入图片说明

Sen*_*ian 24

只需创建一个NestedScrollConnection并将其分配给父视图nestedScroll修饰符:

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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

将其分配给LazyColumn或分配给其父组合视图:

Modifier.nestedScroll(nestedScrollConnection)
Run Code Online (Sandbox Code Playgroud)

示例:

LazyColumn(
    ...
    modifier = Modifier.nestedScroll(nestedScrollConnection)
) {
    items(...) {
       Text("Your text...")
    }
}
Run Code Online (Sandbox Code Playgroud)


Fel*_*ütz 15

正如Ryan M 所写,您可以使用LazyListState.firstVisibleItemIndex. Compose 的神奇之处在于,您只需在if语句中使用它,Compose 就会完成这项工作。请看以下示例,该示例根据第一个可见项目显示不同的文本。同样,您可以根据第一个可见项目选择不同的选项卡。

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(),
                        )
                    }
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • `val firstVisibleIndex by returnedStateOf { listState.firstVisibleItemIndex }` 直接在 compose 函数内访问 listState.firstVisibleItemIndex 可能会对性能产生影响。 (3认同)

Rya*_*ley 7

您可以使用该LazyListState.firstVisibleItemIndex属性(通过获取rememberLazyListState并设置为state参数LazyColumn)并基于该属性设置当前选项卡。

读取该属性被视为在 Compose 中读取模型,因此只要第一个可见项发生更改,它就会触发重组。

如果您想要基于不仅仅是第一个可见项目执行更复杂的操作,则可以使用LazyListState.layoutInfo来获取有关所有可见项目及其位置的信息,而不仅仅是第一个可见项目。

  • @DmytroIvanov 读取一段状态确实会在该状态发生变化时触发重组。这按预期工作。您遇到了什么您认为是错误的情况? (2认同)