Ameen
Ameen

Reputation: 81

Get Room observable list with paging 3

I'm using Paging 3 with a local database using Room, the @Query from Room is the following:

@Query("SELECT * FROM Channel LIMIT :limit OFFSET :offset")
suspend fun getAllChannels(limit: Int, offset: Int): List<Channel>

Then i get my data in the PagingSource like this, and return the LoadResult.Page with my data

channels = channelDao.getAllChannels(
    params.loadSize,
    position * params.loadSize
)

return LoadResult.Page(
    data = channels,
    prevKey = if (position == INITIAL_INDEX) null else position - 1,
    nextKey = if (mData.isEmpty()) null else position + 1
)

in my repository, i get the channels like this:

override fun getAllChannels(): Flow<PagingData<Channel>> {
return Pager(
    PagingConfig(
        pageSize = 20,
        enablePlaceholders = false,
        initialLoadSize = 20
    )
) {
    ChannelPagingSource(
        channelDao
    )
}.flow
}

The problem with this approach is that my view can't observe any modifications happening on the Channel objects, so if it gets updated there's no way to be notified. Is it possible to get observable objects using pagination?

An alternative way is to drop the paging and just return a Flow<List> from Room and consume it, but it's heavy and slowing down the app a little.

Upvotes: 1

Views: 1583

Answers (1)

Daniil Pavlenko
Daniil Pavlenko

Reputation: 573

  1. Add the room-paging dependency in your gradle module. With that Room can handle PagingSource objects in queries.
implementation "androidx.room:room-paging:2.5.0"
  1. Create a method that returns PagingSource<Int, EntityDb> in your @Dao interface. Int - page number / offset, EntityDb - your database model, in your case Channel.
@Query("SELECT * FROM Channel")
fun pagingSource(): PagingSource<Int, Channel>
  1. Get flow of PagingData from your repository.
fun observePagingSource(): Flow<PagingData<Channel>> {
  return Pager(
       config = PagingConfig(pageSize = 20, initialLoadSize = 20),
       pagingSourceFactory = { channelDao.pagingSource() }
  ).flow
}

One important thing - use a single instance of your Dao

If you insert/update/delete data in one instance of your Dao and observe it changes in the other one - you won't receive updates.

Upvotes: 4

Related Questions