Android 分页库 + 房间关系

Ser*_*t69 5 android kotlin android-room android-livedata

我见过的分页库的示例都假设您需要一个Livedata<List<T>>,但是列表位于另一个对象内部的房间关系怎么样?

我的应用程序中有两个实体:Conversation并且Message它们与此类相关:

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

我从不将所有消息作为 来获取LiveData<List<Message>>,而是将单个对话(通过其 ID)及其所有子消息获取。DAO 函数如下所示:

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

我有一个存储库,它只是LiveData<ConversationWithMessages>直接从 DAO 返回数据。

在视图模型中,我有一个conversations保存实时数据的变量:

var conversation: LiveData<ConversationWithMessages> = MutableLiveData()
// ...
conversation = conversationRepository.getConversation(conversationId)
Run Code Online (Sandbox Code Playgroud)

在我的片段中,我只是观察此实时数据来更新适配器:

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

Run Code Online (Sandbox Code Playgroud)

最初我想到PagedList在关系数据类上使用:

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

那么返回 a 的 DAO 查询DataSource将如下所示:

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

但是如何将此数据源转换为配置LiveData<ConversationWithMessages>子级的数据源PagedList<Message> 谷歌有这个例子,但我不知道如何将其应用到这种情况:

@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)
}
Run Code Online (Sandbox Code Playgroud)