Mah*_*alv 34 android android-jetpack-compose android-jetpack-compose-list android-jetpack-compose-lazy-column
我想检查列表是否滚动到列表末尾。然而lazyListState不提供此属性
为什么我需要这个?我想显示一个用于列表“滚动到末尾”的 FAB,如果最后一项已经可见则隐藏它
(注:确实如此,但它是internal
/**
* Non-observable way of getting the last visible item index.
*/
internal var lastVisibleItemIndexNonObservable: DataIndex = DataIndex(0)
Run Code Online (Sandbox Code Playgroud)
不知道为什么)
val state = rememberLazyListState()
LazyColumn(
state = state,
modifier = modifier.fillMaxSize()
) {
// if(state.lastVisibleItem == logs.length - 1) ...
items(logs) { log ->
if (log.level in viewModel.getShownLogs()) {
LogItemScreen(log = log)
}
}
}
Run Code Online (Sandbox Code Playgroud)
那么,如何检查我的内容是否LazyColumn滚动到数据集的末尾?
pau*_*aap 22
以下是您实现它的一种方法:
检查是否滚动到末尾的扩展函数:
fun LazyListState.isScrolledToTheEnd() = layoutInfo.visibleItemsInfo.lastOrNull()?.index == layoutInfo.totalItemsCount - 1
Run Code Online (Sandbox Code Playgroud)
用法示例:
val listState = rememberLazyListState()
val listItems = (0..25).map { "Item$it" }
LazyColumn(state = listState, modifier = Modifier.fillMaxSize()) {
items(listItems) { item ->
Text(text = item, modifier = Modifier.padding(16.dp))
}
}
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.BottomEnd) {
if (!listState.isScrolledToTheEnd()) {
ExtendedFloatingActionButton(
modifier = Modifier.padding(16.dp),
text = { Text(text = "Go to Bottom") },
onClick = { /* Scroll to the end */}
)
}
}
Run Code Online (Sandbox Code Playgroud)
Gab*_*tti 17
从开始,1.4.0-alpha03您可以使用它来LazyListState#canScrollForward检查是否可以向前滚动或者是否位于列表的末尾。
val state = rememberLazyListState()
if (!state.canScrollForward){ /* ... */ }
Run Code Online (Sandbox Code Playgroud)
在您可以使用LazyListState#layoutInfo包含有关可见项目的信息的 之前。如果列表在底部滚动,您可以使用它来检索信息。
既然您正在阅读,state您应该使用它derivedStateOf来避免冗余的重组。
就像是:
val state = rememberLazyListState()
val isAtBottom by remember {
derivedStateOf {
val layoutInfo = state.layoutInfo
val visibleItemsInfo = layoutInfo.visibleItemsInfo
if (layoutInfo.totalItemsCount == 0) {
false
} else {
val lastVisibleItem = visibleItemsInfo.last()
val viewportHeight = layoutInfo.viewportEndOffset + layoutInfo.viewportStartOffset
(lastVisibleItem.index + 1 == layoutInfo.totalItemsCount &&
lastVisibleItem.offset + lastVisibleItem.size <= viewportHeight)
}
}
}
Run Code Online (Sandbox Code Playgroud)
fra*_*ang 13
我正在分享我的解决方案,以防它对任何人有帮助。
它提供了实现问题用例所需的信息,并通过遵循https://developer.android.com/jetpack/compose/lists#control-scroll-position的建议来避免无限重组。
val LazyListState.isLastItemVisible: Boolean
get() = layoutInfo.visibleItemsInfo.lastOrNull()?.index == layoutInfo.totalItemsCount - 1
val LazyListState.isFirstItemVisible: Boolean
get() = firstVisibleItemIndex == 0
Run Code Online (Sandbox Code Playgroud)
data class ScrollContext(
val isTop: Boolean,
val isBottom: Boolean,
)
Run Code Online (Sandbox Code Playgroud)
@Composable
fun rememberScrollContext(listState: LazyListState): ScrollContext {
val scrollContext by remember {
derivedStateOf {
ScrollContext(
isTop = listState.isFirstItemVisible,
isBottom = listState.isLastItemVisible
)
}
}
return scrollContext
}
Run Code Online (Sandbox Code Playgroud)
请注意,派生状态用于避免重组并提高性能。该函数需要列表状态才能在派生状态内进行计算。阅读我上面分享的链接。
@Composable
fun CharactersList(
state: CharactersState,
loadNewPage: (offset: Int) -> Unit
) {
// Important to remember the state, we need it
val listState = rememberLazyListState()
Box {
LazyColumn(
state = listState,
) {
items(state.characters) { item ->
CharacterItem(item)
}
}
// We use our remember composable to get the scroll context
val scrollContext = rememberScrollContext(listState)
// We can do what we need, such as loading more items...
if (scrollContext.isBottom) {
loadNewPage(state.characters.size)
}
// ...or showing other elements like a text
AnimatedVisibility(scrollContext.isBottom) {
Text("You are in the bottom of the list")
}
// ...or a button to scroll up
AnimatedVisibility(!scrollContext.isTop) {
val coroutineScope = rememberCoroutineScope()
Button(
onClick = {
coroutineScope.launch {
// Animate scroll to the first item
listState.animateScrollToItem(index = 0)
}
},
) {
Icon(Icons.Rounded.ArrowUpward, contentDescription = "Go to top")
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
干杯!
我找到的当前解决方案是:
LazyColumn(
state = state,
modifier = modifier.fillMaxSize()
) {
if ((logs.size - 1) - state.firstVisibleItemIndex == state.layoutInfo.visibleItemsInfo.size - 1) {
println("Last visible item is actually the last item")
// do something
}
items(logs) { log ->
if (log.level in viewModel.getShownLogs()) {
LogItemScreen(log = log)
}
}
}
Run Code Online (Sandbox Code Playgroud)
该语句
lastDataIndex - state.firstVisibleItemIndex == state.layoutInfo.visibleItemsInfo.size - 1
通过从第一个可见项目中减去数据集的最后一个索引并检查它是否等于可见项目计数来猜测最后一个项目
| 归档时间: |
|
| 查看次数: |
26109 次 |
| 最近记录: |