sow*_*mia 8 paging clean-architecture android-room android-paging android-paging-3
我的要求是使用干净的架构和离线支持在页面中显示注释。我正在使用 Paging 库进行分页。下面是用于获取笔记的简洁架构图。
注意:请在新选项卡中打开上图并缩放以清晰查看。
我有四层UI、UseCase、Repository和Datasource。我打算抽象数据源的内部实现。为此,我需要NotesEntities在跨越边界之前映射到另一个模型。
class TimelineDao{
@Transaction
@Query("SELECT * FROM NotesEntities ORDER BY timeStamp DESC")
abstract fun getPagingSourceForNotes(): PagingSource<Int, NotesEntities>
}
Run Code Online (Sandbox Code Playgroud)
目前的实施:
internal class NotesLocalDataSourceImpl @Inject constructor(
private val notesDao: NotesDao
) : NotesLocalDataSource {
override suspend fun insertNotes(notes: NotesEntities) {
notesDao.insert(NotesEntities)
}
override fun getNotesPagingSource(): PagingSource<Int, NotesEntities> {
return notesDao.getPagingSourceForNotes()
}
}
Run Code Online (Sandbox Code Playgroud)
预期实施:
internal class NotesLocalDataSourceImpl @Inject constructor(
private val notesDao: NotesDao
) : NotesLocalDataSource {
override suspend fun insertNotes(notes: NotesRepositoryModel) {
notesDao.insert(NotesRepositoryModel.toEntity())
}
override fun getNotesPagingSource(): PagingSource<Int, NotesRepositoryModel> {
return notesDao.getPagingSourceForNotes().map{ it.toNotesRepositoryModel() }
}
}
Run Code Online (Sandbox Code Playgroud)
PagingSource<Int, NotesEntities>我在映射到 时遇到问题PagingSource<Int, NotesRespositoryModel>。据我研究,没有办法映射
PagingSource<Int, NotesEntities>到PagingSource<Int, NotesRespositoryModel>
请告诉我是否有一种干净的方法/解决方法来映射分页源对象。如果有人确定目前没有办法的话。也请留下评论。
请注意:我知道分页允许转换PagingData. 下面是在页面中获取注释的代码片段。它映射NotesEntities到NotesDomainModel. 但后来我想使用NotesRespositoryModel而不是NotesEntitiesin the NotesRespositoryImpl,抽象NotesEntities内部NotesLocalDataSourceImpl 层。
override fun getPaginatedNotes(): Flow<PagingData<NotesDomainModel>> {
return Pager<Int, NotesEntities>(
config = PagingConfig(pageSize = 10),
remoteMediator = NotesRemoteMediator(localDataSource,remoteDataSource),
pagingSourceFactory = localDataSource.getNotesPagingSource()
).flow.map{ it.toDomainModel() }
}
Run Code Online (Sandbox Code Playgroud)
我想到的解决方案:
我没有PagingSource直接使用 in Dao,而是考虑创建一个自定义 PagingSource,它调用 Dao 并将 映射NoteEntities到LocalRepositoryModel.
但随后我需要了解,对数据库的任何更新都不会反映在PagingSource. 我需要在内部处理它。
请让我知道您对此的想法。
如何创建一个实现,PagingSource将所有调用转发到原始调用PagingSource并执行映射,如下所示:
class MappingPagingSource<Key: Any, Value: Any, MappedValue: Any>(
private val originalSource: PagingSource<Key, Value>,
private val mapper: (Value) -> MappedValue,
) : PagingSource<Key, MappedValue>() {
override fun getRefreshKey(state: PagingState<Key, MappedValue>): Key? {
return originalSource.getRefreshKey(
PagingState(
pages = emptyList(),
leadingPlaceholderCount = 0,
anchorPosition = state.anchorPosition,
config = state.config,
)
)
}
override suspend fun load(params: LoadParams<Key>): LoadResult<Key, MappedValue> {
val originalResult = originalSource.load(params)
return when (originalResult) {
is LoadResult.Error -> LoadResult.Error(originalResult.throwable)
is LoadResult.Invalid -> LoadResult.Invalid()
is LoadResult.Page -> LoadResult.Page(
data = originalResult.data.map(mapper),
prevKey = originalResult.prevKey,
nextKey = originalResult.nextKey,
)
}
}
override val jumpingSupported: Boolean
get() = originalSource.jumpingSupported
}
Run Code Online (Sandbox Code Playgroud)
那么用法会是这样的:
override fun getNotesPagingSource(): PagingSource<Int, NotesRepositoryModel> {
return MappingPagingSource(
originalSource = notesDao.getPagingSourceForNotes(),
mapper = { it.toNotesRepositoryModel() },
)
}
Run Code Online (Sandbox Code Playgroud)
关于空pages内PagingState- 将所有加载的页面映射回原始值将过于昂贵,并且房间的分页实现仅使用anchorPosition并且config.initialLoadSize无论如何 - 请参阅此处和此处。
| 归档时间: |
|
| 查看次数: |
673 次 |
| 最近记录: |