标签: android-paging

无法使用 android Paging 库加载下一个数据

我正在尝试使用 Room-Paging-LiveData-ViewModel 显示通话记录列表。没有分页我的代码工作得很好。我也想使用分页。

在我的数据库中,我总共有 25 条通话记录。前 9 个通话记录显示在列表中。

通过调试,我发现在通过 读取视图模型中的数据时Dao,它返回大小为 25 的列表。但其中只有前 9 个是非空的。列表中的所有其他条目都为空。

我期待空数据会很快刷新,因为这是一个分页列表。但问题是 null 永远不会被有效数据刷新。

并且视图模型的observe 方法只被调用一次,只有第一次。

我想我做错了什么。

这是下面的代码

片段

public class CallLogListFragment extends Fragment {
    private static final String TAG = "RecentCallsFragment";

    public static String getTAG() {
        return TAG;
    }

    public static Fragment newInstance() {
        return new CallLogListFragment();
    }

    public CallLogListFragment() {
    }

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        FragmentCallLogListBinding binding = DataBindingUtil.inflate(inflater, R.layout.fragment_call_log_list, container, false);
        CallLogListAdapter adapter = new …
Run Code Online (Sandbox Code Playgroud)

android android-room android-livedata android-paging androidx

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

DataSource.Factory 的 create 方法没有被调用

我正在尝试使用 Paging 库制作字典应用程序。当用户写任何字母时,我将调用 API 并获取包括该字母在内的所有单词。

问题是,当我通过init{}ViewHolder 方法中的 Paging 库调用 API 时,它运行良好。但在那之后,当我尝试编写其他内容并获取相关数据时,分页库甚至不会调用 API。我到处都放了断点,看到第一次之后,create()DataSource.Factory的方法没有被调用。

这是我的代码:

我的活动:

    viewModel = ViewModelProviders.of(this).get(DictionaryViewModel::class.java)
    val adapter = DictionaryRecyclerPagedAdapter()
    recycler.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false)
    recycler.setHasFixedSize(true)
    recycler.adapter = adapter

    RxTextView.textChanges(edtWord)
        .filter { it.isNotBlank() }
        .subscribe({
            adapter.submitList(null)
            viewModel.getWord(it.toString())
            Logger.d(it)

        }, {
            Logger.d(it)
        })



    viewModel.itemPagedList?.observe(this, Observer {
        adapter.submitList(it)
    })
Run Code Online (Sandbox Code Playgroud)

我的视图模型:

var liveDataSource: LiveData<PageKeyedDataSource<Int, DictionaryResult>>? = null
var itemPagedList: LiveData<PagedList<DictionaryResult>>? = null

init {

    getWord("pouya")
}

fun getWord(term: String) {

    val dataSourceFactory = DictionaryDataFactory(term)
    liveDataSource = dataSourceFactory.liveData


    val …
Run Code Online (Sandbox Code Playgroud)

paging android kotlin android-paging

5
推荐指数
2
解决办法
1635
查看次数

分页库中的回调被多次调用

在 May 项目中,我使用了 Android Architecture Components 中的 Paging 库。从用作缓存的 Room db 读取数据,当到达列表末尾时,我使用 Boundary 回调从网络 api 获取新数据。不幸的是,当从 api 调用新的更新时,它会被调用 4 次或更多次,即使方法中有布尔标志,因此新数据是不正确的。

从数据库我返回 Datasource.Factory:

    @Query("SELECT * FROM movieentity ORDER BY popularity DESC")
    fun allMovies(): DataSource.Factory<Int, MovieEntity>
Run Code Online (Sandbox Code Playgroud)

Repository中的方法,基本上我想从api清除缓存并引导下一页:

    override fun allMovies(movieBoundaryCallback: 
    MainViewModel.MovieBoundaryCallback): LiveData<PagedList<Movie>> {
        // Get data source factory from the local cache
        val dataSourceFactory = moviesDao.allMovies().map {
            MovieMapper.fromDb(
                it
            )
        }

        val config: PagedList.Config = PagedList.Config.Builder()
            .setInitialLoadSizeHint(DATABASE_PAGE_SIZE)
            .setPageSize(DATABASE_PAGE_SIZE)
            .setPrefetchDistance(0)
            .build()

        // Get the paged list
        return LivePagedListBuilder(dataSourceFactory, config)
            .setBoundaryCallback(movieBoundaryCallback)
            .build()
    }

    override …
Run Code Online (Sandbox Code Playgroud)

android coroutine kotlin android-paging

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

RecyclerView 分页时跳转到列表中间

我有这个页面,我已经使用 MVVM 和分页进行了设置RecyclerView,并使用Pull 刷新。单击此中的某些项目RecyclerView将导航到另一个片段。

我的问题是每当我第一次加载页面并完全向下滚动时。拉动刷新也可以。

但是当我导航到另一个片段并返回时,一直滚动到顶部,滑动以刷新:RecyclerView将跳转到页面中间(就在我单击以导航到另一个片段的项目上)

我的片段

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val adapter = GroupAdapter<ViewHolder>().apply { add(mainSection) }
        val gridLayoutManager = GridLayoutManager(activity, adapter.spanCount)
        gridLayoutManager.spanSizeLookup = adapter.spanSizeLookup
        with(recyclerView) {
            layoutManager = gridLayoutManager
            setHasFixedSize(true)
            addOnScrollListener(PaginationScrollListener {
                viewModel.onEndOfList()
            })
        }
        recyclerView.adapter = adapter


        pullToRefresh.apply {
            setProgressBackgroundColorSchemeColor(
                ContextCompat.getColor(context, R.color.window_level_2)
            )
            setColorSchemeColors(ContextCompat.getColor(context, R.color.brand_primary))
            setOnRefreshListener { viewModel.onRefresh() }
        }
    }
Run Code Online (Sandbox Code Playgroud)

我的视图模型

    fun onRefresh() {
        page = 0
        widgetItems.clear()
        _widgetListObservable.postValue(widgetItems)
        finishedLoading = false
        isFirstFetch = true …
Run Code Online (Sandbox Code Playgroud)

android kotlin android-recyclerview android-paging

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

使用 Google 的分页库更新 PagedList 中的单个项目

我在 RecyclerView 中有一个简单的 Pokemon 列表,只有 Pokemon 的名字和一个“收藏夹”切换按钮。我正在使用 Android JetPack 的 Paging Library 和 PageKeyedDataSource 来检索小块 Pokemon 并将它们显示给用户。我只希望只要 Activity 没有被销毁,数据就可以持久化(即我不想将数据持久化到 Room 或数据库,而是只要 ViewModel 还活着就让它持久化)。

应用程序截图

我希望能够单击任何 Pokemon 项目上的心形按钮并将 SimplePokemon 模型中的“isFavorite”字段更新为truefalse。根据我的理解,如果我想更改该 PagedList 中的单个项目,我需要使 DataSource 无效,并且理论上应该生成一个新的 PagedList LiveData,该 LiveData 可以提供给适配器并显示在屏幕上。

问题:如何在不需要 Room 或其他数据库的情况下使用分页库更新 PagedList 中的单个项目?

将来,我想将此解决方案扩展到用户可以喜欢帖子的社交媒体提要,但我不知道将社交提要项存储在 Room 等数据库中是否必要(或有效),因为这些提要项不断改变。所以我选择将它们存储在 ViewModel 中,然后在用户每次退出应用程序时清除它们。

到目前为止,这是我的代码:

SimplePokemon.kt:

data class SimplePokemon(
    @SerializedName("name") val name: String,
    @SerializedName("url") val url: String,
    var isFavorite: Boolean = false
)
Run Code Online (Sandbox Code Playgroud)

PokemonViewModel.kt:

class PokemonViewModel(application: Application) : AndroidViewModel(application) {

    private val config …
Run Code Online (Sandbox Code Playgroud)

paging android pagedlist android-paging android-paging-library

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

Android Paging 3 不显示 Loadstate Adapter

我已经按照教程将 Loadstate Adapter 添加到 Android Paging 3 上的 Recyclerview Adapter 但目前,它没有显示。这就是我更新适配器的方式。

 lifecycleScope.launch {
            viewModel.searchProducts(searchParam, channelId, categoryId)
                .collectLatest {
                    binding.allProductRecyclerView.isVisible = true
                    adapter.submitData(it)
                }
        
Run Code Online (Sandbox Code Playgroud)

这就是我添加 LoadState 适配器的方式

  binding.allProductRecyclerView.adapter = adapter.withLoadStateFooter(
        footer = ProductLoadingStateAdapter()
    )
Run Code Online (Sandbox Code Playgroud)

这是 LoadStateAdapter 的要点也是Activity Layout加载状态项

适配器工作正常,我还可以通过添加 LoadStateListener 来获取负载状态。只有负载状态适配器不工作。我已经跟踪并克隆了,它运行良好。我的可能是什么问题?

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

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

分页库 3.0:如何将项目总数传递给列表标题?

请帮帮我。
该应用程序仅用于从https://trefle.io接收植物列表并将其显示在 RecyclerView 中。
我在这里使用分页库 3.0。
任务:我想添加一个标题,其中将显示植物总数。
问题:我只是找不到将总项目的值传递给标题的方法。

    Data model:  
    data class PlantsResponseObject(
    @SerializedName("data")
    val data: List<PlantModel>?,
    @SerializedName("meta")
    val meta: Meta?
) {
    data class Meta(
        @SerializedName("total")
        val total: Int? // 415648
    )
}
   data class PlantModel(
    @SerializedName("author")
    val author: String?,
    @SerializedName("genus_id")
    val genusId: Int?, 
    @SerializedName("id")
    val id: Int?)
Run Code Online (Sandbox Code Playgroud)

数据源类:

class PlantsDataSource(
    private val plantsApi: PlantsAPI,
    private var filters: String? = null,
    private var isVegetable: Boolean? = false

) : RxPagingSource<Int, PlantView>() {

    override fun loadSingle(params: …
Run Code Online (Sandbox Code Playgroud)

android kotlin android-recyclerview android-paging android-paging-library

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

PagingData 是否在 Paging 3 库中默认运行在后台线程上?

后台线程是否PagingData像with一样自动管理PagedList,然后在主线程上返回?

从下面的日志中,PagingDataPagedListPaging 2 的库相比,它似乎没有在 Paging 3 库中的后台线程上运行。

期望基于Paging Codelab示例

  • GithubPagingSource override suspend fun load(...)在 IO 线程上运行。
  • SearchRepositoriesActivity viewModel.searchRepo(query).collectLatest { ... }在主线程上运行。

观察

  • 无论GithubPagingSource override suspend fun load(...)SearchRepositoriesActivity viewModel.searchRepo(query).collectLatest { ... }主线程上运行。

分页 2

螺纹是通过在背景处理PagedListtoLiveData根据文档

如果您使用 LivePagedListBuilder 获取 LiveData,它将在后台线程上为您初始化 PagedLists。

分页 3

Paging 3文档没有提到线程是如何管理的。但是,从日志中,PagingSource似乎在主线程上运行网络请求并在主线程上返回PagingData

我的示例代码

我在CryptoTweets示例应用程序 app-simple …

android kotlin android-thread android-jetpack android-paging

5
推荐指数
2
解决办法
818
查看次数

Android 分页 3:LoadType.APPEND 返回空远程键

我一直在努力研究如何解决我的RemoteMediator's问题APPEND LoadType

在空的 Room DB 上,LoadType流程如下:REFRESH -> PREPEND -> APPEND (remoteKeys = null, endOfPaginationReached = true)

实体和远程键表至少有 10 行,LoadType流程如下:REFRESH -> PREPEND -> APPEND (remoteKeys = prev=null, next=2, endOfPaginationReached = false)

显然,我的问题出在新安装的设备上(带有空的 Room DB),用户不会看到超过 10 个项目,因为APPEND'sstate.lastItemOrNull()正在返回null

到目前为止,这是我的代码:

private suspend fun getRemoteKeysForLastItem(state: PagingState<Int, MovieCache>): MovieRemoteKeys? {
    return state.lastItemOrNull()?.let { movie ->
        appDatabase.withTransaction {
            appDatabase.remoteKeysDao().remoteKeysByImdbId(movie.imdbId)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

对于我的load()功能:

val loadKey = when (loadType) {
            LoadType.REFRESH -> …
Run Code Online (Sandbox Code Playgroud)

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

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

在刷新调用之间清除“PagingDataAdapter”

我正在使用 Paging 3PagingDataAdapter根据给定的查询搜索数据库。每次提交新查询时,我都会调用refresh()适配器上的方法。问题是在加载新数据之前,旧数据仍然存在。

有没有办法从列表中删除所有项目,以便在加载过程中不存在任何项目?此外,我使用ConcatAdapter来附加页眉和页脚以指示加载,因此我的目标是仅在加载数据/提交新查询时显示进度指示器。

更新:

我设法让它工作的唯一方法是调用,adapter.submitData(PagingData.empty())然后是pagingSource.invalidate(). 我不喜欢这个解决方案,因为访问invalidate()存储库层中可用的方法并不容易,我不得不在ViewModel. 有没有更优雅的方法来实现这一目标?我不认为这是一种方法,因为在加载期间刷新列表和删除项目的用例非常普遍,我认为在 Paging 3 库开发过程中已将其考虑在内。

android kotlin android-paging android-paging-3

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