我在 RecyclerView 中有一个简单的 Pokemon 列表,只有 Pokemon 的名字和一个“收藏夹”切换按钮。我正在使用 Android JetPack 的 Paging Library 和 PageKeyedDataSource 来检索小块 Pokemon 并将它们显示给用户。我只希望只要 Activity 没有被销毁,数据就可以持久化(即我不想将数据持久化到 Room 或数据库,而是只要 ViewModel 还活着就让它持久化)。
我希望能够单击任何 Pokemon 项目上的心形按钮并将 SimplePokemon 模型中的“isFavorite”字段更新为true或false。根据我的理解,如果我想更改该 PagedList 中的单个项目,我需要使 DataSource 无效,并且理论上应该生成一个新的 PagedList LiveData,该 LiveData 可以提供给适配器并显示在屏幕上。
问题:如何在不需要 Room 或其他数据库的情况下使用分页库更新 PagedList 中的单个项目?
将来,我想将此解决方案扩展到用户可以喜欢帖子的社交媒体提要,但我不知道将社交提要项存储在 Room 等数据库中是否必要(或有效),因为这些提要项不断改变。所以我选择将它们存储在 ViewModel 中,然后在用户每次退出应用程序时清除它们。
到目前为止,这是我的代码:
SimplePokemon.kt:
data class SimplePokemon(
@SerializedName("name") val name: String,
@SerializedName("url") val url: String,
var isFavorite: Boolean = false
)
Run Code Online (Sandbox Code Playgroud)
PokemonViewModel.kt:
class PokemonViewModel(application: Application) : AndroidViewModel(application) {
private val config …Run Code Online (Sandbox Code Playgroud) paging android pagedlist android-paging android-paging-library
我已经用 Room 实现了分页库。我正在使用单一来源的真相。文章(我的数据)将通过 Retrofit 获取并插入到 Room 数据库中。然后 recyclerview 适配器通过ArticleItemBoundaryCallback监听数据:
public class ArticleItemBoundaryCallback extends PagedList.BoundaryCallback<ArticleModel> {
ArticleRepository repository;
public ArticleItemBoundaryCallback(ArticleRepository repository) {
this.repository =repository;
}
@Override
public void onZeroItemsLoaded() {
super.onZeroItemsLoaded();
repository.getTenArticlesfromFirebaseAndRetrofit(1);
}
@Override
public void onItemAtEndLoaded(@NonNull ArticleModel itemAtEnd) {
super.onItemAtEndLoaded(itemAtEnd);
int page=0;
if (itemAtEnd.getPage() == 0) {
page = itemAtEnd.getPage() + 2;
} else {
page = itemAtEnd.getPage()+1;
}
repository.getTenArticlesfromFirebaseAndRetrofit(page);
}}
Run Code Online (Sandbox Code Playgroud)
Repository 决定是否需要从 Internet 获取数据或查找本地缓存(房间数据库)。
但我的问题是在我的回收站视图末尾没有加载指示器。用户可能不确定他们是否到达列表末尾或正在加载。我看到了这个 google 代码示例, 但我找不到他们添加加载视图的位置。
android android-recyclerview android-architecture-components android-paging-library
我有一个应用程序,它从 API获取158 个项目的列表,将其存储在 Room 中,然后将其显示给用户。RoomDB 是事实的来源。
这是我的 ViewModel 上从数据库获取结果的代码:
private val pagingConfig =
PagingConfig(pageSize = 20, enablePlaceholders = false, maxSize = 300)
fun getList(filters: Filters): Flow<PagingData<Character>> {
return Pager(pagingConfig) {
repository.getCharacters(filters)
}.flow.map {
it.asDomainModel()
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的片段上填充适配器的代码:
private fun fetchData(filters: Filters) {
lifecycleScope.launch {
charactersViewModel.getList(filters).collectLatest { pagedList ->
characterAdapter.submitData(pagedList)
}
}
}
Run Code Online (Sandbox Code Playgroud)
当前行为:
我已经尝试过的:
由于我获取数据异步我使用这段代码从这个尝试的文章,以防止在加载数据时适配器是空的。但它没有用
characterAdapter.stateRestorationPolicy = RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY
Run Code Online (Sandbox Code Playgroud)
我期望达到的目标:
能够滚动到列表底部并在不丢失滚动位置的情况下进行配置更改“无需随着列表变大而增加我的pageSize ”
android kotlin android-architecture-components android-paging android-paging-library
我已经按照教程将 Loadstate Adapter 添加到 Android Paging 3 上的 Recyclerview Adapter 但目前,它没有显示。这就是我更新适配器的方式。
lifecycleScope.launch {
viewModel.searchProducts(searchParam, channelId, categoryId)
.collectLatest {
binding.allProductRecyclerView.isVisible = true
adapter.submitData(it)
}
Run Code Online (Sandbox Code Playgroud)
这就是我添加 LoadState 适配器的方式
binding.allProductRecyclerView.adapter = adapter.withLoadStateFooter(
footer = ProductLoadingStateAdapter()
)
Run Code Online (Sandbox Code Playgroud)
这是 LoadStateAdapter 的要点也是Activity Layout和加载状态项
适配器工作正常,我还可以通过添加 LoadStateListener 来获取负载状态。只有负载状态适配器不工作。我已经跟踪并克隆了它,它运行良好。我的可能是什么问题?
android android-paging android-paging-library android-paging-3
我一直在努力研究如何解决我的RemoteMediator's问题APPEND LoadType。
在空的 Room DB 上,LoadType流程如下:REFRESH -> PREPEND -> APPEND (remoteKeys = null, endOfPaginationReached = true)
实体和远程键表至少有 10 行,LoadType流程如下:REFRESH -> PREPEND -> APPEND (remoteKeys = prev=null, next=2, endOfPaginationReached = false)
显然,我的问题出在新安装的设备上(带有空的 Room DB),用户不会看到超过 10 个项目,因为APPEND'sstate.lastItemOrNull()正在返回null。
到目前为止,这是我的代码:
private suspend fun getRemoteKeysForLastItem(state: PagingState<Int, MovieCache>): MovieRemoteKeys? {
return state.lastItemOrNull()?.let { movie ->
appDatabase.withTransaction {
appDatabase.remoteKeysDao().remoteKeysByImdbId(movie.imdbId)
}
}
}
Run Code Online (Sandbox Code Playgroud)
对于我的load()功能:
val loadKey = when (loadType) {
LoadType.REFRESH -> …Run Code Online (Sandbox Code Playgroud) android android-paging android-paging-library android-paging-3
集跨度的大小比1GridLayoutManager的时候LoadState是Loading在寻呼库。我已经尝试过这个解决方案,但它不起作用。
对于重复的问题:克隆这个官方回购和设置GridLayoutManager在SearchRepositoriesActivity
我的代码在这里
电影列表片段
....
private val adapter = MoviesAdapter()
....
private fun initAdapter() {
val decoration = DividerItemDecoration(requireContext(), DividerItemDecoration.VERTICAL)
binding.rvMovies.addItemDecoration(decoration)
binding.rvMovies.layoutManager = GridLayoutManager(requireContext(), 2)
binding.rvMovies.isNestedScrollingEnabled = true
binding.rvMovies.adapter = adapter.withLoadStateFooter(
footer = MoviesLoadStateAdapter { adapter.retry() }
)
}
Run Code Online (Sandbox Code Playgroud)
电影适配器
class MoviesAdapter(
) : PagingDataAdapter<Movie, MoviesAdapter.ViewHolder>(MOVIE_COMPARATOR) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = ItemMovieListBinding.inflate(LayoutInflater.from(parent.context))
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: …Run Code Online (Sandbox Code Playgroud) android gridlayoutmanager android-recyclerview android-paging-library
我试图找到一种方法来使用 Paging 3 库中的 PagingAdapter 更新回收器视图中的单个项目。我只找到了一种使用 PagingAdapter.refresh() 方法的方法。但是这种方法强制从网络加载所有列表。有人知道如何在不从网络加载所有页面的情况下实现它吗?
android android-jetpack android-paging android-paging-library
我正在使用分页 3,除了初始加载状态外,一切正常。我正在添加withLoadStateFooter但它在第一次调用时从不显示加载状态
这是我的实现
负载状态适配器
class LoadStateAdapter (
private val retry: () -> Unit
): LoadStateAdapter<LoadStateViewHolder>() {
override fun onBindViewHolder(holder: LoadStateViewHolder, loadState: LoadState) {
holder.bindTo(loadState)
}
override fun onCreateViewHolder(
parent: ViewGroup,
loadState: LoadState
): LoadStateViewHolder {
return LoadStateViewHolder.create(parent, retry)
}
}
Run Code Online (Sandbox Code Playgroud)
加载状态视图持有者
class LoadStateViewHolder(
view : View,
private val retryCallback: () -> Unit
) : RecyclerView.ViewHolder(view) {
private val progressBar = view.findViewById<ProgressBar>(R.id.progress_bar)
private val errorMsg = view.findViewById<TextView>(R.id.error_msg)
private val btnRetry = view.findViewById<Button>(R.id.retry_button)
.also {
it.setOnClickListener { retryCallback() }
} …Run Code Online (Sandbox Code Playgroud) 我使用 paging 3.0.0-alpha10 创建了我的 pagingSource 类并且它有效,但是当我将版本更改为 3.0.0-alpha12 时,我收到此错误,这是运行时异常:
java.lang.AbstractMethodError: abstract method "java.lang.Object androidx.paging.PagingDataDiffer.presentNewList(androidx.paging.NullPaddedList, androidx.paging.NullPaddedList, androidx.paging.CombinedLoadStates, int, kotlin.jvm.functions.Function0, kotlin.coroutines.Continuation)"
at androidx.paging.PagingDataDiffer$collectFrom$2$invokeSuspend$$inlined$collect$1$lambda$1.invokeSuspend(PagingDataDiffer.kt:136)
at androidx.paging.PagingDataDiffer$collectFrom$2$invokeSuspend$$inlined$collect$1$lambda$1.invoke(Unknown Source:10)
at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:91)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:161)
at kotlinx.coroutines.BuildersKt.withContext(Unknown Source:1)
at androidx.paging.PagingDataDiffer$collectFrom$2$invokeSuspend$$inlined$collect$1.emit(Collect.kt:133)
at kotlinx.coroutines.flow.FlowKt__ChannelsKt.emitAllImpl$FlowKt__ChannelsKt(Channels.kt:61)
at kotlinx.coroutines.flow.FlowKt__ChannelsKt$emitAllImpl$1.invokeSuspend(Unknown Source:11)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.EventLoop.processUnconfinedEvent(EventLoop.common.kt:69)
at kotlinx.coroutines.DispatchedTaskKt.resumeUnconfined(DispatchedTask.kt:236)
at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:161)
at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:362)
at kotlinx.coroutines.CancellableContinuationImpl.completeResume(CancellableContinuationImpl.kt:479)
at kotlinx.coroutines.channels.AbstractChannel$ReceiveElement.completeResumeReceive(AbstractChannel.kt:899)
at kotlinx.coroutines.channels.ArrayChannel.offerInternal(ArrayChannel.kt:84)
at kotlinx.coroutines.channels.AbstractSendChannel.send(AbstractChannel.kt:135)
at androidx.paging.PageFetcherSnapshot.doInitialLoad(PageFetcherSnapshot.kt:315)
at androidx.paging.PageFetcherSnapshot$doInitialLoad$1.invokeSuspend(Unknown Source:11)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6543)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:440)
at …Run Code Online (Sandbox Code Playgroud) 我正在为 Jetpack 的 Paging 3 Library 苦苦挣扎。
我设置
在PagingSource由空间中创建的。
我知道RemoteMediators 的职责是从网络中获取项目并将它们保存到 Room 数据库中。通过这样做,我们可以使用 Room 数据库作为单一事实点。PagingSource只要我使用整数作为 .Room就可以轻松地为我创建nextPageKeys.
到现在为止还挺好。这是我的 ViewModel 来检索以下列表Sources:
private lateinit var _sources: Flow<PagingData<Source>>
val sources: Flow<PagingData<Source>>
get() = _sources
private fun fetchSources() = viewModelScope.launch {
_sources = sourcesRepository.getSources(
selectedRepositoryUuid,
selectedRef,
selectedPath
)
}
Run Code Online (Sandbox Code Playgroud)
val sources收集在Fragment.
fetchSources()每当三个参数之一发生变化时调用 ( selectedRepositoryUuid, selectedRefor selectedPath)
这是 Paging 调用的存储库 …
android android-room android-jetpack android-paging android-paging-library
android ×10
android-architecture-components ×2
kotlin ×2
paging ×2
android-room ×1
pagedlist ×1