1

我在 Android 中使用新的 Paging 3 库时遇到问题,因为它一次加载所有页面。看了这篇文章:Android Paging (3) load all pages on once

但在我的情况下,RecyclerView 不在任何无限滚动器(嵌套)内,而只是在父级 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>

我的存储库:

   override fun getData(latitude: Double, longitude: Double): LiveData<PagingData<DataPost>> {
         return Pager(
                config = PagingConfig(
                        pageSize = NETWORK_PAGE_SIZE, //is 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 calls that return the body type throw either IOException for network
        // failures, or HttpException for any non-2xx HTTP status codes. This code reports all
        // errors to the UI, but you can inspect/wrap the exceptions to provide more context.
        return try {
            // Key may be null during a refresh, if no explicit key is passed into Pager
            // construction. Use 1 as default, because our API is indexed started at index 0
            val pageNumber = params.key ?: INITIAL_LOAD_SIZE

            // Suspending network load via Retrofit. This doesn't need to be wrapped in a
            // withContext(Dispatcher.IO) { ... } block since Retrofit's Coroutine
            // CallAdapter dispatches on a worker thread.
            val response = myApiService.getData(latitude = latitude, longitude = longitude, page= pageNumber)

            // Since 0 is the lowest page number, return null to signify no more pages should be loaded before it.
            val prevKey = if (pageNumber == INITIAL_LOAD_SIZE) null else pageNumber - 1

            // This API defines that it's out of data when a page returns empty. When out of data, we return `null` to signify no more pages should be loaded
            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)
        }
    }
}

我的视图模型:

 //live data use case
    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)
    }

观察用户界面:

  viewModel.getData(latitude = userLocation.latitude, longitude = userLocation.longitude).observe(viewLifecycleOwner, {
                lifecycleScope.launch {
                    myAdapter.submitData(it)
                }
            })
4

2 回答 2

0

发生这种情况是因为 Paging Adapter 无法解析锚点。

于 2022-02-05T12:55:12.723 回答
-1

就我而言,我使用的是房间,并且这个 recipeId 数据类型很长,我花了五天时间才找到,但是当我将它更改为字符串时,它工作正常。

@Entity(tableName = "table_recipe")
data class RecipeList(
        @PrimaryKey
        @field:SerializedName("recipe_id") var recipeId : String,
        @field:SerializedName("title") var title: String? = null,
)
于 2021-09-06T17:24:49.643 回答