https://kotlinlang.org logo
#compose
Title
# compose
d

Daniel Okanin

05/24/2022, 2:48 PM
Hi everyone, I’m trying to implement infinite lazy column with the following code. But I have a use case that If the shouldLoadMore is true and after the api call for the next page, I still need to ask another page (because I didn’t get enough items ), the shouldLoadMore is still true so the LaunchedEffect isn’t trigger again. Do you have any idea?
Copy code
fun Modifier.pagination(
    state: LazyListState,
    buffer: Int = 10,
    onEndReached: () -> Unit,
) = composed {

    require(buffer >= 0) { "buffer cannot be negative, but was $buffer" }

    val shouldLoadMore = remember {
        derivedStateOf {
            val lastVisibleItem = state.layoutInfo.visibleItemsInfo.lastOrNull() ?: return@derivedStateOf false
            lastVisibleItem.index >= state.layoutInfo.totalItemsCount - 1 - buffer
        }
    }

    LaunchedEffect(shouldLoadMore) {
        snapshotFlow { shouldLoadMore.value }
            .collect { shouldLoadMore ->
                if (shouldLoadMore) onEndReached()
            }
    }
    this
}
@Mor Amit @galex
r

Ravi

05/24/2022, 3:09 PM
Copy code
@Composable
fun Pagination(
    listState: LazyListState,
    buffer: Int = 5,
    flag: Boolean = true,
    action: () -> Unit
) {
    var lastTotalItems = -1
    val loadMore = remember {
        derivedStateOf {
            val layoutInfo = listState.layoutInfo
            val totalItemsNumber = layoutInfo.totalItemsCount
            val lastVisibleItemIndex = (layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: 0) + 1
            val loadMore =
                lastVisibleItemIndex > (totalItemsNumber - buffer) && flag && (lastTotalItems != totalItemsNumber)
            loadMore
        }
    }
    LaunchedEffect(loadMore) {
        snapshotFlow { loadMore.value }
            .distinctUntilChanged()
            .collect {
                if (it) {
                    lastTotalItems = listState.layoutInfo.totalItemsCount
                    action()
                }
            }
    }
}
can u try this, u can ignore
flag
argument.
d

Daniel Okanin

05/24/2022, 4:13 PM
Thanks @Ravi I’ll try it
Hi @Ravi Im not sure this code works for all cases. By set lastTotalItems = listState.layoutInfo.totalItemsCount you are based on the assumption that the code in the derivedStateOf will be executed at least once so the lastTotalItems != totalItemsNumber return false, but this assumption is right? WDYT?
4 Views