Android Paging 3水平滚动RecyclerView一次性加载所有页面问题
Android Paging 3 水平滚动RecyclerView一次性加载所有页面问题
我在使用Android Paging 3库时遇到了一次性加载所有页面的问题,当前场景中RecyclerView没有嵌套在任何可无限滚动的容器(如NestedScrollView)中,仅直接作为ConstraintLayout的子控件,且为水平滚动模式。尝试了多种方案都无法解决,甚至考虑放弃使用该API退回原有实现,相关代码示例如下:
布局文件代码
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/clDashboardMain" android:background="@color/white" android:layout_width="match_parent" android:layout_height="match_parent"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/rv" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginBottom="@dimen/spacing_24" android:clipToPadding="false" android:orientation="horizontal" android:paddingStart="@dimen/spacing_24" android:paddingEnd="@dimen/spacing_24" app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
MyRepository代码
override fun getData(latitude: Double, longitude: Double): LiveData<PagingData<DataPost>> { return Pager( config = PagingConfig( pageSize = NETWORK_PAGE_SIZE, // 取值为20 enablePlaceholders = false ), pagingSourceFactory = { GetPagingSource(myApiService = myApiService, latitude = latitude, longitude = longitude) } ).liveData }
PagingSource文件代码
private const val INITIAL_LOAD_SIZE = 1 class GetPagingSource( private val myApiService: MyApiService, private val latitude: Double, private val longitude: Double ) : PagingSource<Int, DataPost>() { override suspend fun load(params: LoadParams<Int>): LoadResult<Int, DataPost> { // Retrofit调用遇到网络问题会抛出IOException,非2xx状态码会抛出HttpException return try { // 刷新时key可能为null,此处默认从第1页开始加载,后端接口页码从0开始索引 val pageNumber = params.key ?: INITIAL_LOAD_SIZE // Retrofit协程CallAdapter自动调度到工作线程,无需手动切IO线程 val response = myApiService.getData(latitude = latitude, longitude = longitude, page= pageNumber) // 第一页没有上一页,返回null标记没有前置页面 val prevKey = if (pageNumber == INITIAL_LOAD_SIZE) null else pageNumber - 1 // 接口返回空列表说明没有更多数据,返回null标记没有后续页面 val nextKey = if (response.data.isNotEmpty()) pageNumber + 1 else null LoadResult.Page( data = response.data.filter { it.coordinates.longitude > 0.0 }, prevKey = prevKey, nextKey = nextKey ) } catch (e: IOException) { LoadResult.Error(e) } catch (e: HttpException) { LoadResult.Error(e) } } override fun getRefreshKey(state: PagingState<Int, DataPost>): Int? { return state.anchorPosition?.let { state.closestPageToPosition(it)?.prevKey?.plus(1) ?: state.closestPageToPosition(it)?.nextKey?.minus(1) } } }
ViewModel代码
// LiveData用例 fun getData(latitude: Double, longitude: Double): LiveData<PagingData<DataPostUIWrapper>> { val currentLoggedUser = profileContract.getUserProfileId() return postsContract.getPublicPosts(latitude, longitude) .map { it.map { dataPost -> DataPostUIWrapper(dataPost, dataPost.isLikedBy(currentLoggedUser)) } } .cachedIn(viewModelScope) }
UI层观察代码
viewModel.getData(latitude = userLocation.latitude, longitude = userLocation.longitude).observe(viewLifecycleOwner, { lifecycleScope.launch { myAdapter.submitData(it) } })
内容的提问来源于stack exchange,提问作者DM developing
相关产品推荐
相关产品推荐

