https://kotlinlang.org logo
Title
k

Kshitij Patil

02/14/2021, 8:42 AM
Do we have paging library for desktop? Probably Kotlin Multiplatform?
j

John O'Reilly

02/14/2021, 9:26 AM
Following is Kotlin Multiplatform paging library....works at least in Android and iOS....not sure about JVM https://github.com/kuuuurt/multiplatform-paging
fwiw have used it in following project https://github.com/joreilly/MortyComposeKMM
actually, I think it probably is specific to iOS and Android...
k

Kshitij Patil

02/14/2021, 9:39 AM
Yeah I'm aware of this one. I need one for desktop
t

Timo Drick

02/14/2021, 1:27 PM
Implementing paging with flow is not so hard. I think you also want to be able to show the paged data in LazyColumn which is currently not possible out of the box.
k

Kshitij Patil

02/14/2021, 1:28 PM
Yup.. exactly what I'm looking for..
t

Timo Drick

02/14/2021, 1:30 PM
I do experimenting with a custom implementation: This code helps to create a flow which support paging:
/**
 * Executes loadPage until result list is empty and emits the items as flow.
 */
fun <T>pagingFlow(firstPage: Int = 0, maxPages: Int = 100, init: (suspend FlowCollector<T>.() -> Unit)? = null, loadPage: suspend (Int) -> List<T>): Flow<T> {
    var page = firstPage
    return flow {
        init?.invoke(this)
        var emittedValues = true
        while (page < maxPages && emittedValues) {
            emittedValues = false
            loadPage(page).forEach {
                emit(it)
                emittedValues = true
            }
            page++
        }
    }
}
👍 1
Than showing the paging inside of a LazyColumn is unfortunatly much more code. Here you can have a look: https://gitlab.com/compose1/imagebrowser/-/blob/master/src/main/kotlin/de/appsonair/compose/FlowUtils.kt
👍 2
k

Kshitij Patil

02/14/2021, 1:35 PM
Thanks ! Will have a look
t

Timo Drick

02/14/2021, 1:41 PM
So the idea of this code is to have something like this:
val flowCollector = yourFlow.stateList()
//showing a lazy row
FlowRowFor(flow2stateList = flowCollector) { state ->
key(state) {
    when (state) {
        is FlowState.Loading -> LoadingBox()
        is FlowState.Item -> // Your content view
        is FlowState.Error -> ErrorBox()
        is FlowState.Empty -> ErrorBox()
    }
}
}
currently i am updateing it to compose 0.3.0-build152
k

Kshitij Patil

02/14/2021, 1:43 PM
I suppose if we can get to know the scroll position, we can easily trigger the next pages yo have infinite scroll effect
t

Timo Drick

02/14/2021, 1:43 PM
My code handle this too. I do it the same way the paging library from android doing it. Just have a look in the code
But i will do a commit soon. With some bugfixes and build152 compatibility
@Composable
fun <T> FlowColumnFor(
    flow2StateList: Flow2StateList<T>,
    ...,
    itemContent: @Composable LazyItemScope.(FlowState<T>) -> Unit
) {
    LazyColumn(...) {
        itemsIndexed(items = flow2StateList.list) { index, item ->
            flow2StateList.requestListSize(index + 1)
            itemContent(this, item)
        }
    }
}
So every time a element gets visible i request more items from the flow2StateList. You can also define a buffer to preload items before they get visible.
But the code from the Flow2StateList class is so complicated because it also handles all kind of errors and also support retry when loading data fails.
Still the needed code is under 200 lines of code. Thanks to compose and kotlin 😄
Just commited new version. Also renamed Flow2StateList -> FlowListCollector