如何使用 Android androidx.paging.PagingDataAdapter loadStateFlow 显示 Empty、Loading 和 Loaded UI 状态

问题描述

我当前的 android 应用程序使用 Room Paging3 库

implementation 'androidx.paging:paging-runtime-ktx:3.0.0-beta01'

我的要求是显示“数据加载微调器”、无数据可用时的空消息或加载的数据。

我可以在加载时成功显示加载微调器或数据,但是当没有数据显示时它不起作用。

我已经尝试了 SO 上提供的解决方案,但没有一个解决我的问题

我成功处理 Loading 和 Loaded 数据的代码版本类似于:-

viewLifecycleOwner.lifecycleScope.launch {
            adapter.loadStateFlow
                .distinctUntilChangedBy { it.refresh }
                .filter { it.refresh is LoadState.NotLoading }
                .flowOn(Dispatchers.Default)
                .collectLatest {
                    withContext(Dispatchers.Main) {
                        if (adapter.itemCount == 0) (viewModel as HomeViewModel).loading.value = View.VISIBLE
                        else (viewModel as HomeViewModel).loading.value = View.GONE
                    }
                }
        }

我也尝试使用这个投票给 SO 的答案来显示空状态,但是它对我不起作用

adapter.addLoadStateListener { loadState ->
            if (loadState.source.refresh is LoadState.NotLoading && loadState.append.endOfPaginationReached && adapter.itemCount < 1) {
                recycleView?.isVisible = false
                emptyView?.isVisible = true
            } else {
                recycleView?.isVisible = true
                emptyView?.isVisible = false
            }
        }

问题是由 loadStateFlow 发出此条件引起的

(loadState.source.refresh is LoadState.NotLoading && loadState.append.endOfPaginationReached && adapter.itemCount < 1)

正在加载数据时。

我的列表屏幕有下拉刷新,在数据刷新过程中,我首先删除所有现有的行,然后远程获取所有数据。

无论如何我可以使用 PagingDataAdapter.loadStateFlow 来显示我的加载、加载或空的三种状态吗?

我的 ViewModel 代码类似于:-

repository.myData()
          .map { pagingData ->
                 pagingData.map { myDO -> myDO.mapUI() }
               }
           .cachedIn(viewModelScope)
           .collect {
                emit(it)
                    }

我的 Repository 代码类似于:-

fun myData(): Flow<PagingData<MyDO>> {
        return Pager(
            PagingConfig(pageSize = 60,prefetchDistance = 30,enablePlaceholders = false,maxSize = 200)
        ) {
            database.myDAO().fetchMyData()
        }.flow.flowOn(Dispatchers.IO)
    }

我的房间查询类似于这个

@Query("SELECT * from my_table ORDER BY position_date DESC")
fun fetchMyData(): PagingSource<Int,MyDO>

我哪里出错了?

是否有可能实现我想要的功能?

更新

我认为我有两个不同的问题。

第一个是由我的初始数据同步引起的,我使用 Android Workers 从远程源下载数据并插入到我的本地 Room 数据库中。 由于远程数据的组织方式和可用的 Restful API,列表中显示的数据可以由多个工作人员插入。本地插入的数据的这种“分区”导致提交给我的 Paging3 适配器的数据是零星的,这意味着加载状态循环通过加载 -> 未加载 -> 加载 -> 未加载。

我在同步过程中显示列表 Fragment,这导致加载 Spinner 和显示的数据列表之间的屏幕内容“闪烁”

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)