标签: android-paging-3

Android Room Paging3 动态过滤的正确方法

我正在研究新的 Android Room Paging 库

   implementation "androidx.paging:paging-runtime-ktx:3.0.0-alpha09"
Run Code Online (Sandbox Code Playgroud)

我的源数据库表大约有 10,000 行,我按名称字段的第一个字符进行过滤,如下所示:-

@Query("SELECT * from citation_style WHERE citation_style_name LIKE :startsWith ORDER BY citation_style_name ASC")
fun fetch(startsWith: String): PagingSource<Int, CitationStyleDO>
Run Code Online (Sandbox Code Playgroud)

存储库

fun fetch(startsWith: String): Flow<PagingData<CitationStyleDO>> {
    return Pager(
        PagingConfig(pageSize = 60, prefetchDistance = 30, enablePlaceholders = false, maxSize = 200)
    ) { database.citationStyleDao().fetch("$startsWith%") }.flow
}
Run Code Online (Sandbox Code Playgroud)

视图模型

fun fetch(startsWith: String): Flow<PagingData<CitationStyleDO>> {
    return repository.fetch(startsWith).cachedIn(viewModelScope)
}
Run Code Online (Sandbox Code Playgroud)

分段

override fun onStartsWithClicked(startsWith: String) {
    lifecycleScope.launch {
        viewModel.fetch(startsWith).collectLatest { adapter.submitData(it) }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是lifecycleScope.launch {...}每次更改开始字符时重复使用的正确方法吗? …

android android-room android-paging-3

3
推荐指数
1
解决办法
603
查看次数

将分页库从 3.0.0-alpha10 更新到 3.0.0-alpha12 时出现运行时错误

我使用 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)

android kotlin android-paging-library android-paging-3

3
推荐指数
1
解决办法
2466
查看次数

从 PagingSource 的 LoadResult.Error 中提取 Throwable

我的PagingSource加载一些数据。文档建议捕获这样的异常,以便将来进行某些处理LoadResult.Error 。

 override suspend fun load(params: LoadParams<Int>): LoadResult<Int, Item> {
            return try {
                ...
                throw SomeCatchableException()
                ...
            } catch (e: SomeCatchableException) {
                LoadResult.Error(e)
            } catch (e: AnotherCatchableException) {
                LoadResult.Error(e)
            }
        }
Run Code Online (Sandbox Code Playgroud)

但是当我尝试这样处理时:

(adapter as PagingDataAdapter).loadStateFlow.collectLatest { loadState ->

                when (loadState.refresh) {
                    is LoadState.Loading -> {
                        // *do something in UI*
                    }
                    is LoadState.Error -> {
                        // *here i wanna do something different actions, whichever exception type*
                    }
                }
            }
Run Code Online (Sandbox Code Playgroud)

我想知道哪个 Exteption 将被捕获,因为我在参数LoadResult.Error(e)中传递了它(Throwable)

我如何知道loadState处理中的异常类型?

android android-paging-3

3
推荐指数
1
解决办法
2098
查看次数

手动刷新jetpack compose中的分页数据

我正在使用分页撰写库使用远程中介(由本地房间数据库支持)从服务器加载分页数据。有没有办法在滑动刷新的情况下手动刷新中介数据?

android android-paging android-jetpack-compose android-paging-3

3
推荐指数
1
解决办法
6300
查看次数

安卓。如何使用干净架构的分页?

我正在使用MVVM干净的架构编写应用程序。在其中一个屏幕上,我需要使用 来RecyclerView实现pagination。我要使用图书馆Paging3

Android 开发者建议在存储库层使用PagingSource和。RemoteMediator但同时,在许多来源中,我读到数据层和领域层不应该了解有关android框架的任何信息。

但现在我必须在数据层的数据源中使用android库。这在 a 的上下文中正确吗clean architecture

请帮我弄清楚,我不明白如何使用干净的架构实现分页。

android android-recyclerview clean-architecture android-mvvm android-paging-3

3
推荐指数
1
解决办法
1475
查看次数

Jetpack Paging3 RemoteMediator 在 #load 附加上返回相同的 PagingSatate

我正在按照此Codelab使用 github API 和本地数据库构建 paging3 应用程序。虽然前 2 个页面加载良好,但当滚动到底部时尝试加载第 3 个页面时,调解器会遇到循环 - 相同的 PagingState 一遍又一遍地传递给 load() 函数。

只是想知道是否有人知道这里可能的根本原因是什么?

一些实施细节:

RemoteMediator:(prevPage 和 currentPage 来自 github API 的分页响应标头并保存到本地数据库。)

// RepositoryMediator
override suspend fun load(
    loadType: LoadType,
    state: PagingState<Int, Repository>
): MediatorResult {
    return when (loadType) {
        LoadType.REFRESH -> {
            fireRequestForPage(1, true /*clear DB*/)
            return Success(endOfPaginationReached = false)
        }

        LoadType.APPEND -> {
            // !!!!!!! kept getting the same state when APPEND is triggered, resulting in same currentPage and nextPage …
Run Code Online (Sandbox Code Playgroud)

android-paging android-paging-library android-paging-3

2
推荐指数
1
解决办法
1317
查看次数

Room 分页无法正确地将 Flow&lt;PagingData&lt;Model&gt;&gt; 与其他流合并

我正在尝试使用Paging 3库来获取Flow<PagingData<Scan>>Room然后检查是否在 recyclerview 中选择了项目,因此我将此类映射到另一个名为 的类ScanMapper。为了实现此映射,每当用户将某个项目标记为选定时,我都会MapMutableStateFlow<Map<Int, State>>. 这里Map查找 anIndex(Int)得到StateState只是一个enum代表 State 的类UNINITIALISEDUSELECTED并且SELECTED

我将 Map 的值设置为 a StateFlow<Map<Int,State>>。问题是,我试图将Flow<PagingData<Scan>>与 结合起来,StateFlow<Map<Int,State>>以便将 也State作为参数传递给ScanMapper类,因为它State是从 中获取的StateFlow<Map<Int,State>>,而不是原始Scan类的一部分。但是,尽管当我使用该功能将项目标记为在项目单击上选择时,PagingDataAdapter似乎总是会出现这种情况。State UNINITIALISEDmarkSelected(scanId: Int)

请告诉我我在这里缺少什么。

更新

我能够通过使用并使用回收器适配器Flow<List<Scan>>删除库的使用来实现我想要的功能。虽然这不是实际的解决方案,因为它消除了库,但以下更改允许我执行项目选择:Paging 3DiffUtilspagination using paging 3

更新了刀 …

android kotlin-coroutines android-paging-3 kotlin-stateflow

2
推荐指数
1
解决办法
2581
查看次数

尝试使用 Retrofit 发出 get 请求时无法为类 java.lang.Object 创建调用适配器

我在尝试向 NewsApi.org api 发出获取请求时收到以下错误。根据他们的文档,一切似乎都是正确的,我的设置基本上与很多教程和我在 github 上找到的一些示例相同。

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.newsfeed, PID: 12360
    java.lang.IllegalArgumentException: Unable to create call adapter for class java.lang.Object
        for method NewsApi.getBreakingNews
        at retrofit2.ServiceMethod$Builder.methodError(ServiceMethod.java:720)
        at retrofit2.ServiceMethod$Builder.createCallAdapter(ServiceMethod.java:234)
        at retrofit2.ServiceMethod$Builder.build(ServiceMethod.java:160)
        at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:166)
        at retrofit2.Retrofit$1.invoke(Retrofit.java:145)
        at java.lang.reflect.Proxy.invoke(Proxy.java:393)
        at $Proxy1.getBreakingNews(Unknown Source)
        at com.example.newsfeed.data.API.NewsApi$DefaultImpls.getBreakingNews$default(NewsApi.kt:11)
        at com.example.newsfeed.util.NewsPagingSource.load(NewsPagingSource.kt:25)
        at androidx.paging.PageFetcherSnapshot.doInitialLoad(PageFetcherSnapshot.kt:275)
        at androidx.paging.PageFetcherSnapshot$pageEventFlow$1.invokeSuspend(PageFetcherSnapshot.kt:160)
        at androidx.paging.PageFetcherSnapshot$pageEventFlow$1.invoke(PageFetcherSnapshot.kt)
        at androidx.paging.CancelableChannelFlowKt$cancelableChannelFlow$1.invokeSuspend(CancelableChannelFlow.kt:30)
        at androidx.paging.CancelableChannelFlowKt$cancelableChannelFlow$1.invoke(CancelableChannelFlow.kt)
        at androidx.paging.SimpleChannelFlowKt$simpleChannelFlow$1$1$producer$1$1.invokeSuspend(SimpleChannelFlow.kt:57)
        at androidx.paging.SimpleChannelFlowKt$simpleChannelFlow$1$1$producer$1$1.invoke(SimpleChannelFlow.kt)
        at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:91)
        at kotlinx.coroutines.CoroutineScopeKt.coroutineScope(CoroutineScope.kt:194)
        at androidx.paging.SimpleChannelFlowKt$simpleChannelFlow$1$1$producer$1.invokeSuspend(SimpleChannelFlow.kt:52)
        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.internal.DispatchedContinuationKt.resumeCancellableWith(DispatchedContinuation.kt:357)
        at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:30)
        at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable$default(Cancellable.kt:27)
        at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:110)
        at …
Run Code Online (Sandbox Code Playgroud)

android retrofit retrofit2 dagger-hilt android-paging-3

2
推荐指数
1
解决办法
1300
查看次数

Android Compose Paging 3 - 通过网络调用一次性加载所有页面,无需在 LazyColumn 中滚动且无内部滚动

我正在开发一个 Android Compose 项目,其中使用 Paging 3 和 LazyColumn 来显示从网络调用获取的项目列表。Paging 3 的默认行为是根据prefetchDistance用户滚动来加载页面,但在我的例子中,它会加载大约 15 个页面,每个页面在屏幕启动时包含 10 条记录。我尝试过将其设置prefetchDistace为 10,但不起作用。

这是我的代码: ViewModel

class ShowAllNotificationsViewModel @Inject constructor(private val pagingSource: NotificationPagingSource) :
    BaseViewModel() {


    private val _uiState =
        MutableStateFlow<UIState<BaseResponseModel<NotificationResponseModel?>>>(UIState.StateLoading)
    val uiState = _uiState.asStateFlow()

    private val _isRefreshing = MutableStateFlow(false)
    val isRefreshing = _isRefreshing.asStateFlow()


    val items: Flow<PagingData<NotificationModel>> = Pager(
        config = PagingConfig(
            pageSize = 10,
            prefetchDistance = 5,
            enablePlaceholders = false,
        ),
        pagingSourceFactory = { pagingSource }
    )
        .flow
        .cachedIn(viewModelScope)

    fun refreshData() {
        pagingSource.invalidate() …
Run Code Online (Sandbox Code Playgroud)

android android-mvvm android-paging android-jetpack-compose android-paging-3

2
推荐指数
1
解决办法
138
查看次数

实现 Paging Library 3.0 过滤/搜索功能

使用paging 3.0,我成功地实现了它。现在我想为其添加搜索功能。

我只是显示照片库以及分页功能。现在我想在有人搜索时使分页无效

但每当我在搜索上调用无效时。应用程序崩溃..

照片片段.kt

@AndroidEntryPoint
class PhotosFragment : BaseFragment<FragmentPhotosBinding,PhotosFragmentViewModel>(R.layout.fragment_photos),
    SearchView.OnQueryTextListener, LifecycleObserver {
    override val mViewModel: PhotosFragmentViewModel by viewModels()

    private lateinit var photoAdapter: PhotoCollectionAdapter

    override fun onAttach(context: Context) {
        super.onAttach(context)
        activity?.lifecycle?.addObserver(this)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        setHasOptionsMenu(true)
        ///mViewModel.setFilter(getString(R.string.search_filter_default_value))
        initAdapter()
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
    fun onCreated(){
        mViewModel.trendingPhotos.observe(viewLifecycleOwner, Observer {
            photoAdapter.submitData(lifecycle,it)
        })
    }

    private fun initAdapter() {
        photoAdapter = PhotoCollectionAdapter()
        photoAdapter.stateRestorationPolicy = RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY

        mBinding.recyclerView.apply {
            layoutManager = LinearLayoutManager(context)
            setHasFixedSize(true)
            adapter = photoAdapter
        }

        photoAdapter.addLoadStateListener { loadState -> …
Run Code Online (Sandbox Code Playgroud)

android kotlin android-viewmodel android-paging android-paging-3

1
推荐指数
1
解决办法
4901
查看次数

Android Paging 3 无法加载下一页

从自定义分页实现迁移到Jetpack Paging 3 库后,数据未按预期加载。根据以下内容正确处理第一页:PagingConfigPager

internal fun createProductListPager(pagingSource: ProductListPagingSource): Pager<Int, Product> = Pager(
    config = PagingConfig(
        pageSize = 10,
        prefetchDistance = 2,
    ),
    initialKey = 0,
) { pagingSource }
Run Code Online (Sandbox Code Playgroud)

以下是摘录Adapter

public class PagingProductCardAdapter(private val viewBinder: CoreViewBinder) :
    PagingDataAdapter<Listable, RecyclerView.ViewHolder>(viewBinder.getDiffUtils()) {


    public val list: List<Listable>
        get() = snapshot().items


    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
      // ...
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        viewBinder.bind(list[position], holder)
    }
    // ...
}
Run Code Online (Sandbox Code Playgroud)

当滚动到 …

android-paging android-paging-library android-paging-3

1
推荐指数
1
解决办法
3202
查看次数

LazyColumn 错误:需要 LazyPagingItems&lt;TypeVariable(T)&gt; 但找到 List&lt;T&gt;

我正在使用该Paging 3库,LazyColumn并且我想根据购物清单项目的类别对列表进行排序。在下面的代码中,LazyColumn抱怨它正在期待LazyPagingItems<TypeVariable(T)>items属性,但发现了List<ShoppingListItem?>。我怎样才能解决这个问题?

可组合的

val lazyListState = rememberLazyListState()
val successItems = allItemsState.allItems?.collectAsLazyPagingItems()

LazyColumn(
    state = lazyListState,
    modifier = Modifier
        .fillMaxWidth(),
    contentPadding = PaddingValues(
        start = 5.dp,
        end = 5.dp,
        top = 8.dp,
        bottom = 165.dp
    ),
    verticalArrangement = Arrangement.spacedBy(5.dp),
) {
    val groupedByCategory = successItems!!.itemSnapshotList.groupBy { it!!.category }

    groupedByCategory.forEach { (initial, shoppingListItems) ->
        item {
            Text(text = initial)
        }
        items(
            items = shoppingListItems, //Throws error at this line
            key …
Run Code Online (Sandbox Code Playgroud)

android android-paging android-jetpack-compose android-paging-3 android-jetpack-compose-lazy-column

1
推荐指数
1
解决办法
2427
查看次数

如何避免 PagingAdapter 中的重复项?

我已经为我的 android 项目实现了 paging3。为了避免重复的项目,我创建了一个 DiffUtil.ItemCallback 对象,如下所示;

companion object {
    val diffCallback = object : DiffUtil.ItemCallback<Person>() {
        override fun areItemsTheSame(oldItem: Person, newItem: Person): Boolean {
            return oldItem.id == newItem.id
        }

        override fun areContentsTheSame(oldItem: Person, newItem: Person): Boolean {
            return oldItem.id == newItem.id
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我在 PagingDataAdapter 中使用了该对象;

class PersonAdapter : PagingDataAdapter<Person, PersonViewHolder>(diffCallback) 
Run Code Online (Sandbox Code Playgroud)

在视图中,我从 viewModel 获取 PaginData 并将其提交到适配器中。

    private fun observeData() {
    lifecycleScope.launch {
        viewModel.getPeople().observe(this@MainActivity, {
            pagingAdapter.submitData(lifecycle, it)
        })
    }
Run Code Online (Sandbox Code Playgroud)

在我看来,由于 DiffUtil.ItemCallback,具有相同 id 的人将不会被包含在适配器中。但它没有发生。RecyclerView 会打印每个 person 对象,即使它们具有相同的 id。

如何通过id区分数据?为什么 DiffUtil.ItemCallback 不起作用?谢谢。

android kotlin android-diffutils android-paging-3

0
推荐指数
1
解决办法
1488
查看次数