В моем API нет pageSize или уникального идентификатора для каждого продукта, но я все еще реализовал библиотеку Paging 3 и компаратор внутри адаптера, а также с данными в реальном времени для последних изменений.

Теперь проблема заключается в следующем: предположим, что всего в моем API всего 10 элементов, и я извлек их и отобразил в списке. Но как только я прокручиваю 10 элементов, снова отображается 10 элементов, и снова ... и бесконечно !!

Я подозреваю, что у меня 3 ошибки: одна из-за неправильной реализации с разбиением на страницы (следующий предыдущий ключ) или вторая проблема из-за компаратора, а третья, я переопределяю getRefreshKey и передаю state.anchorPosition.

Код:

ProductPagingSource

class ProductPagingSource(
    private val productApi: ProductApi,
) : PagingSource<Int, Products>() {

    override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Products> {
        val position = params.key ?: PRODUCT_STARTING_PAGE_INDEX

        return try {
            val response =
                productApi.getProducts() //Not added load size, position and other params, because in API, there is no data related to that.
            val products = response.products

            LoadResult.Page(
                data = products,
                prevKey = if (position == PRODUCT_STARTING_PAGE_INDEX) null else position - 1,
                nextKey = if (products.isEmpty()) null else position + 1
            )
        } catch (exception: IOException) {
            LoadResult.Error(exception)
        } catch (exception: HttpException) {
            LoadResult.Error(exception)
        }
    }

    override fun getRefreshKey(state: PagingState<Int, Products>): Int? {
        return state.anchorPosition
    }
}

< Сильный > ProductAdapter

class ProductAdapter(context: Context?) :
    PagingDataAdapter<Products, ProductAdapter.ProductViewHolder>(PRODUCT_COMPARATOR) {
    private lateinit var mContext: Context

    init {
        if (context != null) {
            mContext = context
        }
    }

.
.
.

 private val PRODUCT_COMPARATOR = object : DiffUtil.ItemCallback<Products>() {
            override fun areItemsTheSame(oldItem: Products, newItem: Products) =
                oldItem.name == newItem.name

            override fun areContentsTheSame(oldItem: Products, newItem: Products) =
                oldItem == newItem
        }
    }
}
-1
Sychi Singh 27 Фев 2021 в 21:09

1 ответ

Лучший ответ

Когда вы говорите, что он всегда выбирает одни и те же данные, он, вероятно, всегда может получать одни и те же данные.
Ваша бизнес-логика ошибочна, потому что productApi.getProducts() должен получать по ключу.
В случае, если API должен быть действительно настолько дрянным, чтобы не поддерживать разбиение на страницы, вы все равно могли бы использовать репозиторий, а затем запрашивать локальный SQLite с поддержкой разбиения на страницы.

2
Martin Zeitler 27 Фев 2021 в 18:24