【问题标题】:How to implement SwipeRefreshLayout with the new Paging Library如何使用新的分页库实现 SwipeRefreshLayout
【发布时间】:2021-10-14 16:07:56
【问题描述】:

我有一个向用户显示项目列表的活动,它使用分页库。我的问题是,当用户向下滑动屏幕以便再次从服务器获取数据时,我无法重新加载列表。

这是我的数据源工厂:

public class CouponListDataSourceFactory extends DataSource.Factory {
    private CouponListDataSource dataSource;

    public CouponListDataSourceFactory(CouponRepository repository, String token, String vendorId) {
        dataSource = new CouponListDataSource(repository, token, vendorId);
    }

    @Override
    public DataSource create() {
        return dataSource;
    }
}

这就是我创建 PagedList 的方法

PagedList.Config config = new PagedList.Config.Builder()
                .setInitialLoadSizeHint(15)
                .setPageSize(10)
                .build();
LiveData<PagedList<Coupon>> couponsLiveData = new LivePagedListBuilder<>(dataSourceFactory, config).build();

【问题讨论】:

  • 简单地使你的自定义DataSource失效,你有什么DataSource
  • @pskink 我使用 PositionalDataSource。我在我的数据源上调用了 invalidate 方法,但它什么也没做。无效后我还应该做什么?
  • 你使用PagedListAdapter?你的代码是什么? PagedList#isDetached() 返回什么?
  • 是的,我使用 LivePagedListBuilder 创建它,并将它从我的视图模型返回到我的活动。
  • 你传递给LivePagedListBuilder构造函数的DataSource.Factory的代码是什么?你会发布任何个来源吗?

标签: android android-architecture-components


【解决方案1】:

调用mDataSource.invalidate()方法后,mDataSource会失效,并通过DataSource.Factory.create()方法创建新的DataSource实例,所以提供很重要在 DataSource.Factory.create() 方法中每次都新建 DataSource() 实例,不要每次都提供相同的 DataSource 实例

mDataSource.invalidate() 不起作用,因为在失效后,CouponListDataSourceFactory 提供了相同的、已经失效的 DataSource 实例。

修改后的CouponListDataSourceFactory如下图所示,调用mCouponListDataSourceFactory.dataSource.invalidate()方法进行刷新或者不保留dataSource实例在工厂内部,我们可以在 LiveData>.getValue().getDataSource().invalidate()

上调用 invalidate 方法
public class CouponListDataSourceFactory extends DataSource.Factory {

private CouponListDataSource dataSource;

private CouponRepository repository;
private String token;
private String vendorId;

public CouponListDataSourceFactory(CouponRepository repository, String token, String vendorId) {
    this.repository = repository;
    this.token = token;
    this.vendorId = vendorId;
}

@Override
public DataSource create() {
    dataSource = new CouponListDataSource(repository, token, vendorId);
    return dataSource;
}
}

【讨论】:

  • 我尝试使 liveDataSource 无效,但是当无效时,适配器为空并在加载完成后再次显示。你能告诉我什么时候开始刷新,适配器不是空的,刷新完成后适配器将被替换
  • 对不起,你能澄清你的问题吗,我无法理解主要思想。但是here is the working example 带有分页库并滑动刷新
  • 我想了解如何在分页库上应用刷新操作,我尝试过但看起来很难看,当操作开始时滑动刷新我的适配器为空
  • 您好,很抱歉回复晚了。我刚刚推送了Paging Demo app的新版本,它通过显示滑动刷新指示器来获取初始数据
  • 嗨,首先是原因。 ModelDataSource.loadInitial() 方法已经在后台线程调用,并且期望在调用 loadInitial 方法之后数据已经被获取。因此,将 caroutine 的启动方法替换为 Network 类中的 runblocking 将解决问题。 Here is the Network class。另一种方法是同步调用retrofit api方法,不用在loadInitial方法中多余使用caroutin,
【解决方案2】:

在 ViewModel 类中添加方法

 public void refresh() {

    itemDataSourceFactory.getItemLiveDataSource().getValue().invalidate();
}

您可以从 Activity/Fragment 中使用

 swipeRefreshLayout.setOnRefreshListener(() -> yourviewModel.refresh());

在 reyclerView 加载时隐藏刷新布局

yourViewModel.itemPagedList.observe(this, allProposalModel -> {


        mAdapter.submitList(model);
        swipeRefreshLayout.setRefreshing(false); //here..


    });

【讨论】:

  • 在调用无效列表后不再加载。我应该执行其他操作还是它自己起作用?
  • 就我而言,看到日志,它会刷新所有数据,但没有显示。我还应该做什么?
猜你喜欢
  • 2019-09-27
  • 1970-01-01
  • 2022-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-10
  • 2014-08-10
相关资源
最近更新 更多