(译) 展示分页列表

原文链接

本指南以分页库概述为基础,描述了如何在应用程序 UI 中向用户显示信息列表,尤其是在此信息发生变化时。

连接 UI 到 视图模型

你可以将 LiveData 的实例连接到 PagedListAdapter ,如以下代码段所示:

1
2
3
4
5
6
7
8
9
10
11
public class ConcertActivity extends AppCompatActivity {
private ConcertAdapter adapter = new ConcertAdapter();
private ConcertViewModel viewModel;

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
viewModel = ViewModelProviders.of(this).get(ConcertViewModel.class);
viewModel.concertList.observe(this, adapter::submitList);
}
}

当数据源提供 PagedList 的新实例时,Activity 会将这些对象发送到适配器。 PagedListAdapter 实现定义了如何计算更新,并自动处理分页和列表差异。因此,你的ViewHolder 只需要绑定到特定提供的项目:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class ConcertAdapter
extends PagedListAdapter<Concert, ConcertViewHolder> {
protected ConcertAdapter() {
super(DIFF_CALLBACK);
}

@Override
public void onBindViewHolder(@NonNull ConcertViewHolder holder,
int position) {
Concert concert = getItem(position);

// Note that "concert" can be null if it's a placeholder.
holder.bindTo(concert);
}

private static DiffUtil.ItemCallback<Concert> DIFF_CALLBACK
= ... // See Implement the diffing callback section.
}

PagedListAdapter 使用 PagedList.Callback 对象处理页面加载事件。当用户滚动时,PagedListAdapter 调用 PagedList.loadAround() 以向底层的 PagedList 提供关于它应该从 DataSource 获取哪些项的提示

注意:PagedList是内容不可变的。这意味着,虽然可以将新内容加载到PagedList的实例中,但加载的项本身一旦加载就无法更改。因此,如果 PagedList中 的内容更新,则PagedListAdapter 对象将接收包含更新信息的全新 PagedList。

实现差异回调

以下示例显示了 areContentsTheSame() 的手动实现,它比较了相关的对象字段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private static DiffUtil.ItemCallback<Concert> DIFF_CALLBACK =
new DiffUtil.ItemCallback<Concert>() {

@Override
public boolean areItemsTheSame(Concert oldItem, Concert newItem) {
// The ID property identifies when items are the same.
return oldItem.getId() == newItem.getId();
}

@Override
public boolean areContentsTheSame(Concert oldItem, Concert newItem) {
// Don't use the "==" operator here. Either implement and use .equals(),
// or write custom data comparison logic here.
return oldItem.equals(newItem);
}
};

由于适配器包含比较项的定义,因此适配器会在加载新的 PagedList 对象时自动检测对这些项的更改。因此,适配器会在 RecyclerView 对象中触发高效的项目动画。

使用不同的适配器类型进行区分

如果你选择不从 PagedListAdapter 继承 - 例如当您使用提供自己的适配器的库时 - 你仍然可以通过直接使用 AsyncPagedListDiffer 对象来使用分页库适配器的 diffing 功能。

在 UI 中提供占位符

如果你希望 UI 在应用程序完成获取数据之前显示列表,你可以向用户显示占位符列表项。 PagedList 通过将列表项数据显示为 null 来处理这种情况,直到加载数据。

注意:默认情况下,分页库启用此占位符行为。
占位符具有以下好处:

  • 支持滚动条:PagedList 为 PagedListAdapter 提供列表项的数量。此信息允许适配器绘制一个滚动条,传达列表的完整大小。加载新页面时,滚动条不会跳转,因为列表不会更改大小。
  • 无需加载微调器:由于列表大小已知,因此无需提醒用户正在加载更多项目。占位符本身传达了这些信息。

但是,在添加对占位符的支持之前,请记住以下前提条件:

  • 需要可数数据集:Room 持久化库中的 DataSource 实例可以有效地计算其项目。但是,如果你使用的是自定义本地存储解决方案或仅限网络的数据体系结构,则确定数据集中包含的项目数量可能很昂贵甚至无法实现。
  • 需要适配器来考虑卸载的项目:用于准备通胀列表的适配器或表示机制需要处理空列表项。例如,将数据绑定到 ViewHolder 时,需要提供默认值来表示卸载的数据。
  • 需要相同大小的项目视图:如果列表项目大小可以根据其内容(例如社交网络更新)进行更改,则项目之间的交叉淡化看起来不太好。我们强烈建议在这种情况下禁用占位符。
非典型前端coder wechat
想要随时Follow我的最新博客,可扫码关注我的公众号