博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
android架构组件之paging如何优雅实现加载提示
阅读量:4181 次
发布时间:2019-05-26

本文共 6104 字,大约阅读时间需要 20 分钟。

在使用paging的过程中,使用起来是很方便,但也发现一些问题,比如往下滑的时候,没有加载的提示(数据正在加载中),这个时候就需要我们去处理了,数据加载可能是成功了,可能是失败了,也可能是全部加载完成了,加载过程中还有加载的结果都是需要一个友好的提示的,我们看到好多APP应用都是在item底部会有一个友好的提示,所有这边文章就是来实现如何在底部添加一个友好提示的item,数据加载成功后会自动消失。

加载数据的几种状态

加载数据可以分为加载过程中,加载成功,加载失败,数据全部加载完成,如果还有其他状态可自行添加,根据这些状态就可以定义一个枚举类来描述这几种情况:

public enum RequestDataState {    //加载过程中    LOADING,     //加载成功    SUCCESS,     //加载失败    FAIL,     //全部加载完成    COMPLETE}

数据加载

对于paging来说,数据加载的功能全部交给了DataSource,DataSource有三个子类,我们可以根据不同的需求去实现对应的子类,这里以PageKeyedDataSource为例进行说明,其他的类似,为了处理加载数据的几种状态并且通用性强,可以将这个功能抽象出来,之后要同步加载状态的全部去实现这个类就可以了,这个还比较简单,类的定义如下:

public abstract class PageKeyedLoadDataSource
extends PageKeyedDataSource
{ //存储请求数据后的状态 private MutableLiveData
netDataStateLiveData = new MutableLiveData<>(); public MutableLiveData
getNetDataStateLiveData() { return netDataStateLiveData; } @Override public void loadAfter(@NonNull LoadParams
params, @NonNull LoadCallback
callback) { updateNetState(RequestDataState.LOADING); RequestDataState requestDataState = loadAfter1(params, callback); //加载数据失败后,为下次重试加载提供参数 if (requestDataState == RequestDataState.FAIL) { this.params = params; this.callback = callback; } updateNetState(requestDataState); } private LoadParams
params; private LoadCallback
callback; //数据加载失败后可以尝试重新进行加载 public void retryAfter(){ loadAfter(params,callback); } private void updateNetState(RequestDataState state) { netDataStateLiveData.postValue(state); } /** * @param params * @param callback * @return true加载数据成功 false加载数据失败 */ public abstract RequestDataState loadAfter1(@NonNull LoadParams
params, @NonNull LoadCallback
callback);}

这里提供了一个抽象方法loadAfter1(),返回请求数据的状态就好,这样封装好后,其他使用都是一样的,所以这里还是比较方便的,接下来才是重点。

数据加载状态显示

对于数据显示,自然想到的就是PagedListAdapter了,这里就是通过它来显示加载状态的,问题又来了,如何才能解耦呢?就是再次封装下PagedListAdapter,处理对请求数据状态的显示,如下:

public abstract class PagedListLoadAdapter
extends PagedListAdapter
{ //定义加载数据显示的几种状态 private static final int TYPE_LOAD_LOADING = 1002; private static final int TYPE_LOAD_ALL_COMPLETE = 1003; private static final int TYPE_LOAD_FAIL = 1004; //当前请求数据的状态 private RequestDataState state; private LifecycleOwner owner; PagedListLoadAdapter(@NonNull DiffUtil.ItemCallback diffCallback, LifecycleOwner owner) { super(diffCallback); this.owner = owner; } @NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int type) { //这里加载过程中、加载失败、加载全部完成使用的是同一个布局,可根据需要自行定义 if (type == TYPE_LOAD_LOADING || type == TYPE_LOAD_ALL_COMPLETE || type == TYPE_LOAD_FAIL) { View inflate = View.inflate(viewGroup.getContext(), R.layout.item_load_more, null); return new LoadingViewHolder(inflate); } return onCreateViewHolder1(viewGroup, type); } public abstract VH onCreateViewHolder1(@NonNull ViewGroup viewGroup, int type); @Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) { //根据加载状态对item的提示的处理 if (getItemViewType(position) == TYPE_LOAD_LOADING) { ((LoadingViewHolder) viewHolder).bindTo("正在加载数据,请稍候..."); return; } if (getItemViewType(position) == TYPE_LOAD_ALL_COMPLETE) { ((LoadingViewHolder) viewHolder).bindTo("所有数据已全部加载完成"); return; } if (getItemViewType(position) == TYPE_LOAD_FAIL) { ((LoadingViewHolder) viewHolder).bindTo("加载数据失败"); return; } onBindViewHolder1(viewHolder, position); } public abstract void onBindViewHolder1(@NonNull RecyclerView.ViewHolder viewHolder, int position); @Override public int getItemCount() { if (state == RequestDataState.LOADING || state == RequestDataState.COMPLETE || state == RequestDataState.FAIL) { return super.getItemCount() + 1; } return super.getItemCount(); } @Override public int getItemViewType(int position) { if (position == getItemCount() - 1 && (state == RequestDataState.LOADING)) return TYPE_LOAD_LOADING; if (position == getItemCount() - 1 && (state == RequestDataState.FAIL)) return TYPE_LOAD_FAIL; if (position == getItemCount() - 1 && (state == RequestDataState.COMPLETE)) { View view = new TextView((Activity) owner); //3秒后不显示加载完成的提示 view.postDelayed(() -> { PagedListLoadAdapter.this.state = RequestDataState.SUCCESS; notifyItemChanged(getItemCount()); }, 3000); return TYPE_LOAD_ALL_COMPLETE; } return super.getItemViewType(position); } @Override public void onCurrentListChanged(@Nullable PagedList
currentList) { super.onCurrentListChanged(currentList); PagedList
pagedList = getCurrentList(); if (null == pagedList) { return; } DataSource
dataSource = pagedList.getDataSource(); if (dataSource instanceof PageKeyedLoadDataSource) { MutableLiveData
netDataStateLiveData = ((PageKeyedLoadDataSource) dataSource).getNetDataStateLiveData(); //对加载数据状态进行监听 netDataStateLiveData.observe(owner, this::setNetState); } } public void setNetState(RequestDataState state) { this.state = state; notifyItemChanged(getItemCount()); } private class LoadingViewHolder extends RecyclerView.ViewHolder { private TextView loadView; public LoadingViewHolder(@NonNull View itemView) { super(itemView); loadView = itemView.findViewById(R.id.load_msg); } public void bindTo(String s) { loadView.setText(s); } }}

到这就算是完成了,其他所有的操作所有的和正常使用paging是一样的,只是继承的类换成是上面的PageKeyedLoadDataSource和PagedListLoadAdapter,这里需要注意PagedListLoadAdapter中定义的加载布局需要我们去定义,这样做完后,网络加载数据的提示就会自动完成。如果想要实现下拉刷新,可以使用android原生的SwipeRefreshLayout,同时需要替换掉PagedList,也就是重新在创建一个LivePagedListBuilder就ok了。

 

 

转载地址:http://mwhai.baihongyu.com/

你可能感兴趣的文章
使用librtmp进行H264与AAC直播
查看>>
H.264 RTP Streaming
查看>>
H264实时编码及NALU,RTP传输(续)(ZZ)
查看>>
H.264 基础及 RTP 封包详解
查看>>
VS2015 编译live555源码
查看>>
VS2015下编译libeXosip2.5.0
查看>>
x264码率控制参数详解
查看>>
X264在VS2015环境下编译
查看>>
linphone-iphone最新源码编译
查看>>
解读x264_param_default 参数
查看>>
ios编译linphone 开启x264编译
查看>>
x264命令参数与代码对应关系
查看>>
关于编译x264时出现的for Cortex-A8 erratum because it has no mapping symbols问题
查看>>
M3U8格式讲解及实际应用分析
查看>>
流媒体开发之--HLS--M3U8解析(2): HLS草案
查看>>
CMake 手册详解(一)
查看>>
CMake 手册详解(二)
查看>>
CMake 手册详解(三)
查看>>
CMake 手册详解(四)
查看>>
CMake 手册详解(五)
查看>>