8.Paging

Paging概述

1
Paging 库可帮助您加载和显示来自本地存储或网络中更大的数据集中的数据页面。此方法可让您的应用更高效地利用网络带宽和系统资源;

使用 Paging 库的优势

1
2
3
4
5
- 分页数据的内存中缓存。该功能有助于确保您的应用在处理分页数据时高效使用系统资源。
- 内置的请求去重功能,可确保您的应用高效利用网络带宽和系统资源。
- 可配置的RecyclerView适配器,会在用户滚动到已加载数据的末尾时自动请求数据。
- 对 Kotlin 协程和数据流以及LiveData和 RxJava 的一流支持。
- 内置对错误处理功能的支持,包括刷新和重试功能。
1
implementation 'androidx.paging:paging-runtime:2.1.0'

//没有认真研究,写真实项目时再认真学习下,以下是简单的使用案例,真实项目可能不一样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* PagedList: 数据源获取的数据最终靠PagedList来承载。
* 对于PagedList,我们可以这样来理解,它就是一页数据的集合。
* 每请求一页,就是新的一个PagedList对象。
*/
public class StudentViewModel extends ViewModel {

// 看源码:@1 listLiveData 数据怎么来的
private final LiveData<PagedList<Student>> listLiveData;

public StudentViewModel() {
StudentDataSourceFactory factory = new StudentDataSourceFactory();

// 初始化 ViewModel,如何生产一页数据出来给我!
this.listLiveData = new LivePagedListBuilder<Integer, Student>(factory, Flag.SIZE)
.setBoundaryCallback(new MyBoundaryCallback())
.build();
}
// TODO 暴露数据出去
public LiveData<PagedList<Student>> getListLiveData() {
return listLiveData;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

public class RecyclerPagingAdapter extends PagedListAdapter<Student, RecyclerPagingAdapter.MyRecyclerViewHolder> {
// TODO 比较的行为
private static DiffUtil.ItemCallback<Student> DIFF_STUDNET = new
DiffUtil.ItemCallback<Student>() {
// 一般是比较 唯一性的内容, ID
@Override
public boolean areItemsTheSame(@NonNull Student oldItem, @NonNull Student newItem) {
return oldItem.getId().equals(newItem.getId());
}

// 对象本身的比较
@Override
public boolean areContentsTheSame(@NonNull Student oldItem, @NonNull Student newItem) {
return oldItem.equals(newItem);
}
};

protected RecyclerPagingAdapter() {
super(DIFF_STUDNET);
}

@NonNull
@Override
public MyRecyclerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, null);
return new MyRecyclerViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull MyRecyclerViewHolder holder, int position) {
Student student = getItem(position);

// item view 出来了, 分页库还在加载数据中,我就显示 Id加载中
if (null == student) {
holder.tvId.setText("Id加载中");
holder.tvName.setText("Name加载中");
holder.tvSex.setText("Sex加载中");
} else {
holder.tvId.setText(student.getId());
holder.tvName.setText(student.getName());
holder.tvSex.setText(student.getSex());
}
}

// Item 优化的 ViewHolder
public static class MyRecyclerViewHolder extends RecyclerView.ViewHolder {

TextView tvId;
TextView tvName;
TextView tvSex;

public MyRecyclerViewHolder(View itemView) {
super(itemView);
tvId = itemView.findViewById(R.id.tv_id); // ID
tvName = itemView.findViewById(R.id.tv_name); // 名称
tvSex = itemView.findViewById(R.id.tv_sex); // 性别
}
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
RecyclerPagingAdapter recyclerPagingAdapter;
StudentViewModel viewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

recyclerView = findViewById(R.id.recycle_view);
recyclerPagingAdapter = new RecyclerPagingAdapter();

// 最新版本初始化 viewModel
viewModel = new ViewModelProvider(this, new ViewModelProvider.NewInstanceFactory())
.get(StudentViewModel.class);

// LiveData 观察者 感应更新
viewModel.getListLiveData().observe(this, new Observer<PagedList<Student>>() {
@Override
public void onChanged(PagedList<Student> students) {
// 再这里更新适配器数据
recyclerPagingAdapter.submitList(students);
}
});
recyclerView.setAdapter(recyclerPagingAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}
}