显示分页列表

本指南基于 分页库概述,描述了如何在应用的 UI 中向用户展示信息列表,尤其是在这些信息发生变化时。

将您的 UI 连接到您的视图模型

您可以将 LiveData<PagedList> 的实例连接到 PagedListAdapter,如下面的代码片段所示

Kotlin

class ConcertActivity : AppCompatActivity() {
    private val adapter = ConcertAdapter()

    // Use the 'by viewModels()' Kotlin property delegate
    // from the activity-ktx artifact
    private val viewModel: ConcertViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState);
        viewModel.concerts.observe(this, Observer { adapter.submitList(it) })
    }
}

Java

public class ConcertActivity extends AppCompatActivity {
    private ConcertAdapter adapter = new ConcertAdapter();
    private ConcertViewModel viewModel;

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

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

Kotlin

class ConcertAdapter() :
        PagedListAdapter<Concert, ConcertViewHolder>(DIFF_CALLBACK) {
    override fun onBindViewHolder(holder: ConcertViewHolder, position: Int) {
        val concert: Concert? = getItem(position)

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

    companion object {
        private val DIFF_CALLBACK = ... // See Implement the diffing callback section.
    }
}

Java

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 中提取哪些项目。

实现差异回调

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

Kotlin

private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<Concert>() {
    // The ID property identifies when items are the same.
    override fun areItemsTheSame(oldItem: Concert, newItem: Concert) =
            oldItem.id == newItem.id

    // If you use the "==" operator, make sure that the object implements
    // .equals(). Alternatively, write custom data comparison logic here.
    override fun areContentsTheSame(
            oldItem: Concert, newItem: Concert) = oldItem == newItem
}

Java

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 对象来使用分页库适配器的差异计算功能。

在您的 UI 中提供占位符

在您的应用完成数据提取之前希望您的 UI 显示列表的情况下,您可以向用户显示占位符列表项。PagedList 通过在加载数据之前将列表项数据显示为 null 来处理这种情况。

占位符具有以下优点

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

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

  • 需要可计数的数据集:来自 Room 持久性库DataSource 实例可以有效地计算其项目数。但是,如果您使用的是自定义本地存储解决方案或 仅网络数据架构,则确定有多少项目构成您的数据集可能会很昂贵,甚至不可能。
  • 需要适配器来处理未加载的项目:您用于准备要展开的列表的适配器或表示机制需要处理空列表项。例如,当将数据绑定到 ViewHolder 时,您需要提供默认值来表示未加载的数据。
  • 要求相同大小的项目视图:如果列表项的大小会根据其内容而改变,例如社交网络更新,则项目之间的交叉淡入淡出效果不佳。在这种情况下,我们强烈建议禁用占位符。

提供反馈

通过以下资源与我们分享您的反馈和想法

问题跟踪器
报告问题,以便我们修复错误。

其他资源

要了解有关分页库的更多信息,请参阅以下资源。

示例

Codelabs

视频