Android Paging Library + Room relationships

Viewed 316

The examples I've seen of the paging library all assume you need a Livedata<List<T>>, but how about Room relationships where the list is inside another object?

I have two entities in my app: Conversation and Message and they're related with this class:

data class ConversationWithMessages(
    @Embedded val conversation: Conversation,
    @Relation(
        parentColumn = "conversation_gid",
        entityColumn = "conversationId"
    )
    val messages: List<Message>
)

I never fetch all messages as a LiveData<List<Message>>, but a single conversation (by its ID) plus all its child messages. The DAO function looks like this:

@Transaction
@Query("SELECT * FROM conversations WHERE conversation_gid =:conversationId LIMIT 1")
fun getConversationLiveDataById(conversationId: Long): LiveData<ConversationWithMessages>

I have a Repository which simply returns the LiveData<ConversationWithMessages> straight from the DAO.

In the Viewmodel, I have a conversations variable holding the livedata:

var conversation: LiveData<ConversationWithMessages> = MutableLiveData()
// ...
conversation = conversationRepository.getConversation(conversationId)

On my fragment, I just observe this livedata to update the adapter:

private val conversationObserver = Observer<ConversationWithMessages> {
    it?.let {
        // it.messages gives me the list I use to update
    }
}

Initially I thought of using PagedList on the relationship data class:

data class ConversationWithMessages(
    @Embedded val conversation: Conversation,
    @Relation(
        parentColumn = "conversation_gid",
        entityColumn = "conversationId"
    )
    val messages: PagedList<Message>
)

Then the DAO query which returns a DataSource would look like this:

@Transaction
@Query("SELECT * FROM conversations WHERE conversation_gid =:conversationId LIMIT 1")
fun getConversationLiveDataById(conversationId: Long): DataSource.Factory<Int, ConversationWithMessages>

But how do I transform this DataSource into a LiveData<ConversationWithMessages> where the child PagedList<Message> is configured? Google has this example, but I don't see how to apply it to this case:

@Dao
interface ConcertDao {
    // The Int type parameter tells Room to use a PositionalDataSource
    // object, with position-based loading under the hood.
    @Query("SELECT * FROM concerts ORDER BY date DESC")
    fun concertsByDate(): DataSource.Factory<Int, Concert>
}

class ConcertViewModel(concertDao: ConcertDao) : ViewModel() {
    val concertList: LiveData<PagedList<Concert>> =
            concertDao.concertsByDate().toLiveData(pageSize = 50)
}
0 Answers
Related