0

I want to use Paging 3 Library and combine results from 3 tables such that:

Result from Table1 are shown first. When Results from Table1 has reached end of their data then results from Table2 are shown.

When results from Table2 have reached end of their data then results from Table3 are shown.

When results of Table3 reaches end of the data then there is nothing to display Please advise

Cpp crusaders
  • 117
  • 2
  • 10

2 Answers2

2

You can create your own PagingSource which will accept multiple PagingSource in a constructor and load them one after another.

class MultipleSourcesSource<T : Any>(
    val sources: List<PagingSource<Int, T>>
) : PagingSource<Int, T>() {

    private var currentIndex = 0

    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, T> {
        if (currentIndex == sources.size) {
            return LoadResult.Page(
               data = emptyList(),
               prevKey = null,
               nextKey = null
            )
        }

        val result = sources[currentIndex].load(params)
        currentIndex++

        return LoadResult.Page(
               data = result.data,
               prevKey = if (currentIndex == 0) currentIndex else currentIndex - 1,
               nextKey = currentIndex
        )
        return result
    }

    override fun getRefreshKey(state: PagingState<Int, T>) = null
}

You also will have to create PagingSource's for your tables:

class Table1DataSource(
    private val database: MyDatabase
) : PagingSource<Int, Item>() {

    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Item> {
        val items = database.getData() // get data from your source
        return LoadResult.Page(
            data = items,
            prevKey = null,
            nextKey = null
        )
    }

    override fun getRefreshKey(state: PagingState<Int, Table1Item>) = null
}

And finally you can just use MultipleSourcesSource for load your data:

val mediator = MultipleSourcesSource(listOf(
    // here are table sources
))

// Create a Pager with the mediator
val pager = Pager(
    config = PagingConfig(pageSize = pageSize),
    pagingSourceFactory = { mediator }
)
.flow
.collect { results -> 
    // TODO: collect results
}
Mikhail Guliaev
  • 1,168
  • 1
  • 6
  • 14
  • I really appreciate the quick response.. but in this case... first page will be from table 1, second page will be from table 2 and so on ... but we needed first all results from table 1 then table 2 and so on... – Cpp crusaders May 05 '23 at 16:53
  • You can just remember the last row of result from a table N and when counter will be on the last data source, just set in on 0 and read again from the datasource #1 – Mikhail Guliaev May 05 '23 at 17:27
  • Hi @Mikhail I really appreciate the quick reply what worked for me was ConcatAdapter it just worked out of the box for me.. I hooked up 2 instances of pagingAdapter to ConcatAdapter instance1 i passed in table1 instance2 i passed in table2 – Cpp crusaders May 08 '23 at 16:09
0

ConcatAdapter fixed the use case for me.

I hooked up 2 instances of pagingAdapter to ConcatAdapter instance1 I passed in a pagingsource of table1 instance2 I passed in a pagingsource of table2

https://developersbreach.com/merge-multiple-adapters-with-concatadapter-android/

Cpp crusaders
  • 117
  • 2
  • 10