MVVM架构下Firestore瀑布流RecyclerView分页加载异常排查
Firestore分页加载异常:切换Fragment时一次性加载所有数据块
需求:实现Firestore数据分页加载,滚动RecyclerView至底部时获取新文档。
问题:切换到包含RecyclerView的Fragment时,会一次性加载所有10条一组的数据块,而非按需滚动加载。
DI模块
@Module @InstallIn(SingletonComponent::class) object AppModule { @Provides @Singleton fun provideQueryByName() = FirebaseFirestore.getInstance() .collectionGroup(Constants.POSTS_COLLECTION).whereEqualTo("doc_id", "jetpack") .orderBy(Constants.POSTS_ORDER_BY, Query.Direction.DESCENDING).limit(Constants.PAGE_SIZE.toLong()) }
PagingSource实现
class FirestorePagingSource ( private val queryProductsByName: Query ) : PagingSource<QuerySnapshot, PostsModel>() { override fun getRefreshKey(state: PagingState<QuerySnapshot, PostsModel>): QuerySnapshot? { return null } override suspend fun load(params: LoadParams<QuerySnapshot>): LoadResult<QuerySnapshot, PostsModel> { return try { val currentPage = params.key ?: queryProductsByName.get().await() Log.e("data",currentPage.size().toString()) val lastVisibleProduct = currentPage.documents[currentPage.size() - 1] val nextPage = queryProductsByName.startAfter(lastVisibleProduct).get().await() LoadResult.Page( data = currentPage.toObjects(PostsModel::class.java), prevKey = null, nextKey = nextPage ) } catch (e: Exception) { LoadResult.Error(e) } } }
Adapter实现
class PostsAdapter : PagingDataAdapter<PostsModel, PostsAdapter.PostsViewHolder>(Companion) { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PostsViewHolder { val layoutInflater = LayoutInflater.from(parent.context) val dataBinding = PostsDataBinding.inflate( layoutInflater, parent, false ) return PostsViewHolder(dataBinding) } override fun onBindViewHolder(holder: PostsViewHolder, position: Int) { val product = getItem(position) ?: return holder.bindProduct(product) val density = Resources.getSystem().displayMetrics.density if (position == 0) { holder.itemView.layoutParams.height = 420 * density.toInt() } else { holder.itemView.layoutParams.height = 450 * density.toInt() } } companion object : DiffUtil.ItemCallback<PostsModel>() { override fun areItemsTheSame(oldItem: PostsModel, newItem: PostsModel): Boolean { return oldItem.upload_date == newItem.upload_date } override fun areContentsTheSame(oldItem: PostsModel, newItem: PostsModel): Boolean { return oldItem == newItem } } inner class PostsViewHolder( private val dataBinding: PostsDataBinding ) : RecyclerView.ViewHolder(dataBinding.root) { fun bindProduct(product: PostsModel) { dataBinding.posts = product } } }
ViewModel实现
@HiltViewModel class PostsViewModel @Inject constructor( private val queryPostsByName: Query ) : ViewModel() { val flow = Pager( PagingConfig( pageSize = 10 ) ) { FirestorePagingSource(queryPostsByName) }.flow.cachedIn(viewModelScope) }
Fragment相关方法
private fun setProgressBarAccordingToLoadState() { dataBinding.rvUserPosts.adapter = adapter } private fun getPosts() { lifecycleScope.launch { viewModel2.flow.collectLatest { adapter.submitData(it) } } } private fun setPostsAdapter() { lifecycleScope.launch { adapter.loadStateFlow.collectLatest { dataBinding.progressBar.isVisible = it.append is LoadState.Loading } } }
RecyclerView Item布局
<?xml version="1.0" encoding="utf-8"?> <data class="PostsDataBinding"> <variable name="posts" type="com.ansh.jetpack.mvvm.data.PostsModel" /> </data> <androidx.cardview.widget.CardView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_margin="2dp" app:cardCornerRadius="8dp"> <ImageView android:id="@+id/ivCover" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" app:imageUrl="@{posts.img_hd_url}" android:src="@color/cardview_dark_background" /> </androidx.cardview.widget.CardView>
RecyclerView布局
<androidx.recyclerview.widget.RecyclerView android:id="@+id/rvUserPosts" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" app:layoutManager= "androidx.recyclerview.widget.StaggeredGridLayoutManager" app:spanCount="2" tools:listitem="@layout/rv_user_posts_item" />
内容的提问来源于stack exchange,提问作者Himanshu Yadav Anshu
相关产品推荐
相关产品推荐

