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)
}