Paging
逐步从数据源中加载数据
目前所学习的paging都是基于对SQLite数据库的访问,并且是结合了Room的使用的。
改写Dao
原先的查询操作返回的是LiveData<List<Student>>类型的数据,由于现在是要逐步加载数据,需要将返回的数据类型修改为DataSource.Factory<Integer,Student>,Integer为key,Student为value。
@Dao
public interface StudentDao {
@Query("select * from student_table order by id")
DataSource.Factory<Integer,Student> getAllStudents();
}
改写RecyclerView的Adapter
现在的Adapter要继承自PagedListAdapter,新增构造方法以检查逐步加载的内容是否已经加载过。
public class MyPagedAdapter extends PagedListAdapter<Student, MyPagedAdapter.MyViewHolder> {
protected MyPagedAdapter() {
super(new DiffUtil.ItemCallback<Student>() {
@Override
public boolean areItemsTheSame(@NonNull Student oldItem, @NonNull Student newItem) {
return oldItem.getId()==newItem.getId();
}
@Override
public boolean areContentsTheSame(@NonNull Student oldItem, @NonNull Student newItem) {
return oldItem.getStudentNumber()==newItem.getStudentNumber();
}
});
}
}
在绑定视图时,由于数据是逐步加载的,可能会导致此时数据还未加载完全,需要调用PagedListAdapter的getItem方法来检查是否为空。
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
Student student=getItem(position);
if (student==null){
holder.textView.setText("loading");
}else {
holder.textView.setText(String.valueOf(student.getStudentNumber()));
}
}
设置读出的数据
allStudentLivePaged=new LivePagedListBuilder<>(studentDao.getAllStudents(),3)
.build();//数据来源;数据个数
allStudentLivePaged.observe(this, new Observer<PagedList<Student>>() {
@Override
public void onChanged(final PagedList<Student> students) {
pagedAdapter.submitList(students);
students.addWeakCallback(null, new PagedList.Callback() {
@Override
public void onChanged(int position, int count) {
Log.i("Tag","onChange:"+students);
}
@Override
public void onInserted(int position, int count) {
}
@Override
public void onRemoved(int position, int count) {
}
});
}
});
将读出的数据存储到PagedList<Student>,括号内的两个参数,第一个是数据源,第二个是一次读出的大小,如果要访问的数据没有加载就会源源不断地从数据源中读出。
当数据发生改变时,还是需要将改变的数据提交到Adapter的,只不过现在并不是使用notifyDataSetChanged()方法,而是直接使用PagedAdapter的submitList方法。
还可以通过addWeakCallBack方法对数据发生改变时进行回调。