PS:原文首发于微信公众号:躬行之(jzman-blog)
阅读本文之前,可先阅读同系列 Android Jetpack 组件文章如下 :
- Android Jetpack组件之Lifecycle篇
- Android Jetpack组件之LiveData详解
- Android Jetpack组件之ViewModel篇
- Android Jetpack组件之DataBinding详解
- Android Jetpack组件之使用可观察的数据对象
本文将介绍 Paging Library 库的使用,其源码解析将在下篇文章中介绍,Paging Library 组件是 Android Jetpack 的一部分,是 Google 推出的官方分页组件,如果项目中使用了 Google 新推出的官方架构组件,如 LiveData、Lifecycle、ViewModel 等,就可以尝试将该分页组件引入自己的项目,它的优点是无痕加载更多数据,一定程度上提高用户体验。
简述一下使用 pageing 组件分页加载数据的过程,DataSource 负责从网络或数据库加载数据,将数据存储在 PagedList 中,使用 submitList 提交数据到 PagedListAdapter,当数据发生变化时会在后台线程中计算数据差异,最后 PagedListAdapter 通知 RecyclerView 更新数据。
- 准备数据
- 引入Paging Library组件
- 自定义DataSource
- 配置分页参数
- 加载显示数据
- 测试效果
- Paging Library源码解析
准备数据
这里使用干货集中营的开源 Api 来进行测试,具体如下:
public interface CommonAPI {
// 这里使用干货集中营开源API:http://gank.io/api/search/query/listview/category/Android/count/10/page/1
@GET("api/search/query/listview/category/Android/count/8/page/{page}")
Call<List<DataBean.ResultsBean>> getArticleList1(@Path("page") int page);
}
引入Paging Library组件
引入 Paging Library 库如下:
def paging_version = "2.1.0"
// androidx
implementation "androidx.paging:paging-runtime:$paging_version"
// 老版本 (page library 2.0.0-rc01)
implementation "android.arch.paging:runtime:$paging_version"
这里使用的时 androidx 最新版本。
自定义DataSource
自定义 DataSource 加载数据,这里加载的网络数据,使用 PageKeyedDataSource 更合适,继承 PageKeyedDataSource 自定义 DataSource 如下:
// 自定义DataSource
public class MDataSource extends PageKeyedDataSource<String, DataBean.ResultsBean> {
private static final String TAG = MDataSource.class.getSimpleName();
private int mPage = 1;
public MDataSource() {
}
// 初始化
@Override
public void loadInitial(@NonNull LoadInitialParams<String> params, @NonNull final LoadInitialCallback<String, DataBean.ResultsBean> callback) {
Log.i(TAG, "--loadInitial-->");
CommonAPI api = RetrofitApi.getInstance().mRetrofit.create(CommonAPI.class);
Call<List<DataBean.ResultsBean>> call = api.getArticleList1(mPage);
call.enqueue(new Callback<List<DataBean.ResultsBean>>() {
@Override
public void onResponse(Call<List<DataBean.ResultsBean>> call, Response<List<DataBean.ResultsBean>> response) {
Log.i(TAG, "--onResponse-->" + response.toString());
if (response.isSuccessful() && response.code() == 200) {
List<DataBean.ResultsBean> data = response.body();
callback.onResult(data, "before", "after");
}
}
@Override
public void onFailure(Call<List<DataBean.ResultsBean>> call, Throwable t) {
Log.i(TAG, "--onFailure-->" + t.getMessage());
}
});
}
// 加载上一页
@Override
public void loadBefore(@NonNull LoadParams<String> params, @NonNull LoadCallback<String, DataBean.ResultsBean> callback) {
Log.i(TAG, "--loadBefore-->" + params.key);
}
// 加载下一页
@Override
public void loadAfter(@NonNull final LoadParams<String> params, @NonNull final LoadCallback<String, DataBean.ResultsBean> callback) {
Log.i(TAG, "--loadAfter-->" + params.key);
mPage++;
CommonAPI api = RetrofitApi.getInstance().mRetrofit.create(CommonAPI.class);
Call<List<DataBean.ResultsBean>> call = api.getArticleList1(mPage);
call.enqueue(new Callback<List<DataBean.ResultsBean>>() {
@Override
public void onResponse(Call<List<DataBean.ResultsBean>> call, Response<List<DataBean.ResultsBean>> response) {
Log.i(TAG, "--onResponse-->" + response.toString());
if (response.isSuccessful() && response.code() == 200) {
List<DataBean.ResultsBean> data = response.body();
callback.onResult(data, params.key);
}
}
@Override
public void onFailure(Call<List<DataBean.ResultsBean>> call, Throwable t) {
Log.i(TAG, "--onFailure-->" + t.getMessage());
}
});
}
}
很简单没有什么多余的东西,细节可以参考后文中的源码解析,创建一个工厂方便数据变化是创建新的 DataSource 如下:
// MDataSource创建工厂
public class MDataSourceFactory extends DataSource.Factory<String, DataBean.ResultsBean> {
public MDataSourceFactory() {
}
@NonNull
@Override
public DataSource<String, DataBean.ResultsBean> create() {
MDataSource mDataSource = new MDataSource();
return mDataSource;
}
}
配置分页参数
在 ViewModel 中创建 PagedList.Config 并进行分页参数配置,创建 DataSource 工厂对象,最终生成支持分页的 LiveData 数据,具体参考如下:
// ViewModel
public class MViewModel extends ViewModel {
private int pageSize = 20;
// PagedList配置
private PagedList.Config config = new PagedList.Config.Builder()
.setInitialLoadSizeHint(pageSize)//设置首次加载的数量
.setPageSize(pageSize)//设置每页加载的数量
.setPrefetchDistance(2)//设置距离每页最后数据项来时预加载下一页数据
.setEnablePlaceholders(false)//设置是否启用UI占用符
.build();
// DataSource.Factory
private DataSource.Factory<String,DataBean.ResultsBean> factory = new MDataSourceFactory();
// LiveData
private LiveData<PagedList<DataBean.ResultsBean>> mPagedList = new LivePagedListBuilder<>(factory, config)
.build();
public LiveData<PagedList<DataBean.ResultsBean>> getPagedList() {
return mPagedList;
}
}
加载显示数据
这里使用 LiveData 监听加载的数据,然后使用 sumbitList 将数据提交给 PagedListAdapter,会在后台线程中对比新旧数据的差异,最后更新 RecyclerView ,具体如下:
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private RecyclerView mRecyclerView;
private ArticleAdapter mAdapter;
private MViewModel mViewModel;
private static DiffUtil.ItemCallback<DataBean.ResultsBean> itemCallback = new DiffUtil.ItemCallback<DataBean.ResultsBean>() {
@Override
public boolean areItemsTheSame(@NonNull DataBean.ResultsBean oldItem, @NonNull DataBean.ResultsBean newItem) {
return oldItem.getGanhuo_id() == newItem.getGanhuo_id();
}
@Override
public boolean areContentsTheSame(@NonNull DataBean.ResultsBean oldItem, @NonNull DataBean.ResultsBean newItem) {
return oldItem.equals(newItem);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = findViewById(R.id.rvData);
mAdapter = new ArticleAdapter(itemCallback);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.setAdapter(mAdapter);
ViewModelProvider mViewModelProvider = new ViewModelProvider(this,
new ViewModelProvider.AndroidViewModelFactory(getApplication()));
mViewModel = mViewModelProvider.get(MViewModel.class);
}
public void getData(View view) {
mViewModel.getPagedList().observe(this, new Observer<PagedList<DataBean.ResultsBean>>() {
@Override
public void onChanged(PagedList<DataBean.ResultsBean> dataBeans) {
Log.i(TAG, "--onChanged-->");
mAdapter.submitList(dataBeans);
}
});
}
}
测试效果
可以关注公众号:躬行之(jzman-blog) 交流学习。
今天的文章Android Jetpack组件之Paging Library使用篇分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/21451.html