paging 的作用就是自动加载, 不需要监听列表的滚动状态
引入依赖包
dependencies {
def paging_version = "2.1.1"
implementation "androidx.paging:paging-runtime:$paging_version" // For Kotlin use paging-runtime-ktx
// alternatively - without Android dependencies for testing
testImplementation "androidx.paging:paging-common:$paging_version" // For Kotlin use paging-common-ktx
// optional - RxJava support
implementation "androidx.paging:paging-rxjava2:$paging_version" // For Kotlin use paging-rxjava2-ktx
}
假设是从数据库中读取数据的场景
@Query("SELECT * FROM STUDENT")
DataSource.Factory queryAll();
数据适配器 使用 PagedListAdapter
public class PageAdapter extends PagedListAdapter {
public PageAdapter() {
super(new DiffUtil.ItemCallback() {
@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.equals(newItem);
}
});
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_paging, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
Student item = getItem(position);
// 这里 item 可能会为空
if (item != null) {
holder.number.setText(String.valueOf(item.getStudent_number()));
}
}
static class ViewHolder extends RecyclerView.ViewHolder {
TextView number;
ViewHolder(@NonNull View itemView) {
super(itemView);
number = itemView.findViewById(R.id.number);
}
}
}
在Controller 层 中
private LiveData> allStudents;
recyclerView.setLayoutManager(new LinearLayoutManager(activity));
adapter = new PageAdapter();
recyclerView.setAdapter(adapter);
studentDao = StudentDatabase.getInstance(activity).getStudentDao();
// 两个参数 是数据来源 和 分页的个数
allStudents = new LivePagedListBuilder<>(studentDao.queryAll(), 20)
.build();
allStudents.observe(getViewLifecycleOwner(), new Observer>() {
@Override
public void onChanged(PagedList students) {
// 刷新
adapter.submitList(students);
}
});
用在网络请求的情景
涉及到的类 DataSource , DataSource.Factory, PagedListAdapter
/**
* 分页加载的 DataSource ; -->PageKeyedDataSource
* DataSource 有三个子类 ,根据不同的api 实现不同的子类
*/
class ArticleDataSource : PageKeyedDataSource() {
private val repository = ArticleRepository()
/**
* 初始加载
*/
override fun loadInitial(
params: LoadInitialParams,
callback: LoadInitialCallback
) {
repository.getArticle(0).execute(object : BaseObserver() {
override fun success(t: Article) {
var datas = t.datas
Log.e("=====", "$datas")
callback.onResult(datas, null, 1)
}
override fun fail(msg: String) {
Log.e("=====", msg)
}
})
}
/**
* 加载下一页
*/
override fun loadAfter(params: LoadParams, callback: LoadCallback) {
repository.getArticle(params.key).execute(object : BaseObserver() {
override fun success(t: Article) {
var datas = t.datas
callback.onResult(datas, (params.key + 1))
Log.e("=====", "$datas")
}
override fun fail(msg: String) {
Log.e("=====", msg)
}
})
}
override fun loadBefore(params: LoadParams, callback: LoadCallback) {
}
}
DataSource.Factory
class ArticleDataSourceFactory : DataSource.Factory() {
override fun create(): DataSource {
return ArticleDataSource()
}
}
在ViewModel 中只需要 实例化 实例化 DataSource.Factory 转 LiveData
class RecyclerViewModel : ViewModel() {
val articleLiveData = ArticleDataSourceFactory().toLiveData(1)
/**
* 如果外部需要调用 下拉刷新,重头加载的
* 在这里把 datasource 置空就会重新生成一个新的 DataSource()
* 里面的 方法就会重新执行。
*/
fun resetQuery() {
articleLiveData.value?.dataSource?.invalidate()
}
}
Activity 里头
mViewModel?.articleLiveData?.observe(viewLifecycleOwner, Observer {
adapter.submitList(it)
})
在把 Adapter 继承 PagedListAdapter 就可以自动加载更多了 .