Android开发操作案例分享!

移动开发者 2016-08-04

Android开发操作案例分享!

AndroidLRecyclerView操作案例分享-实现下拉刷新、滑动到底部自动加载,一直想抽空写下这个开源项目www.lampbrother.net,但是各种原因没有抽时间,今天还是趁着工作间隙写下了这篇博客,与大家分享。

简介

LRecyclerView是支持addHeaderView、addFooterView、下拉刷新、分页加载数据的RecyclerView。

它对RecyclerView控件进行了拓展,给RecyclerView增加HeaderView、FooterView,并且不需要对你的Adapter做任何修改。

主要功能

下拉刷新、滑动到底部自动加载下页数据;

可以方便添加Header和Footer;

头部下拉样式可以自定义;

具备item点击和长按事件。

网络错误加载失败点击Footer重新请求数据;

可以动态为FooterView赋予不同状态(加载中、加载失败、滑到最底等)。

感谢

如果我比别人看得远些,那是因为我站在巨人们的肩上。(牛顿)

本开源控件是基于HeaderAndFooterRecyclerView开源项目而来,在原基础上进行了扩充。在此感谢兄弟连教育(www.lampbrother.net)的分享

Gradle

Step1.在你的根build.gradle文件中增加JitPack仓库依赖。

allprojects{

repositories{

jcenter()

maven{url"https://jitpack.io"}

}

}

Step2.在你的model的build.gradle文件中增加LRecyclerView依赖。

compile'com.github.jdsjlzx:LRecyclerView:1.0.0'

使用

添加HeaderView、FooterView

mDataAdapter=newDataAdapter(this);

mDataAdapter.setData(dataList);

mHeaderAndFooterRecyclerViewAdapter=newHeaderAndFooterRecyclerViewAdapter(this,mDataAdapter);

mRecyclerView.setAdapter(mHeaderAndFooterRecyclerViewAdapter);

mRecyclerView.setLayoutManager(newLinearLayoutManager(this));

//addaHeaderView

RecyclerViewUtils.setHeaderView(mRecyclerView,newSampleHeader(this));

//addaFooterView

RecyclerViewUtils.setFooterView(mRecyclerView,newSampleFooter(this));

注意:

mHeaderAndFooterRecyclerViewAdapter=newHeaderAndFooterRecyclerViewAdapter(this,mDataAdapter);

HeaderAndFooterRecyclerViewAdapter提供了一些实用的功能,使用者不用关心它的实现,只需构造的时候把自己的mDataAdapter以参数形式传进去即可。

下拉刷新和加载更多

为了大家使用方便,将需要用的方法统一封装到接口LScrollListener中。

mRecyclerView.setLScrollListener(newLRecyclerView.LScrollListener(){

@Override

publicvoidonRefresh(){

}

@Override

publicvoidonScrollUp(){

}

@Override

publicvoidonScrollDown(){

}

@Override

publicvoidonBottom(){

}

@Override

publicvoidonScrolled(intdistanceX,intdistanceY){

}

});

LScrollListener实现了nRefresh()、onScrollUp()、onScrollDown()、onBottom()、onScrolled五个事件,如下所示:

voidonRefresh();//pulldowntorefresh

voidonScrollUp();//scrolldowntoup

voidonScrollDown();//scrollfromuptodown

voidonBottom();//loadnextpage

voidonScrolled(intdistanceX,intdistanceY);//movingstate,youcangetthemovedistance

onRefresh()——RecyclerView下拉刷新事件;

onScrollUp()——RecyclerView向上滑动的监听事件;

onScrollDown()——RecyclerView向下滑动的监听事件;

onBottom()——RecyclerView滑动到底部的监听事件;

onScrollDown()——RecyclerView正在滚动的监听事件;

加载更多(加载下页数据)

从上面的LScrollListener介绍中就可以看出,实现加载更多只要在onBottom()接口中处理即可。

下拉刷新

为了达到和Listview的下拉刷新效果,本项目没有借助SwipeRefreshLayout控件,而是在自定义RecyclerView头部实现的刷新效果。

这里的下拉刷新效果借鉴了开源库:AVLoadingIndicatorView

mRecyclerView.setRefreshProgressStyle(ProgressStyle.BallSpinFadeLoader);

mRecyclerView.setArrowImageView(R.drawable.iconfont_downgrey);

AVLoadingIndicatorView库有多少效果,LRecyclerView就支持多少下拉刷新效果,当然你也可以自定义下拉效果。

下拉刷新逻辑处理:

从上面的LScrollListener介绍中就可以看出,实现下拉刷新只要在onRefresh()接口中处理即可。

加载网络异常处理

加载数据时如果网络异常或者断网,LRecyclerView为你提供了重新加载的机制。

网络异常出错代码处理如下:

RecyclerViewStateUtils.setFooterViewState(getActivity(),mRecyclerView,getPageSize(),LoadingFooter.State.NetWorkError,mFooterClick);

privateView.OnClickListenermFooterClick=newView.OnClickListener(){

@Override

publicvoidonClick(Viewv){

RecyclerViewStateUtils.setFooterViewState(getActivity(),mRecyclerView,getPageSize(),LoadingFooter.State.Loading,null);

requestData();

}

};

上面的mFooterClick就是我们点击底部的Footer时的逻辑处理事件,很显然我们还是在这里做重新请求数据操作。

点击事件和长按事件处理

在Hongyang前辈的博客中有下描述:

ClickandLongClick

不过一个挺郁闷的地方就是,系统没有提供ClickListener和LongClickListener。

不过我们也可以自己去添加,只是会多了些代码而已。

实现的方式比较多,你可以通过mRecyclerView.addOnItemTouchListener去监听然后去判断手势,当然你也可以通过adapter中自己去提供回调,这里我们选择后者,前者的方式,大家有兴趣自己去实现。

Hongyang大神选择了后者,LRecyclerView早期选择了前者,经过实践总结,在adapter中实现点击事件会好点。

先看下怎么使用:

mHeaderAndFooterRecyclerViewAdapter.setOnItemClickLitener(newOnItemClickLitener(){

@Override

publicvoidonItemClick(Viewview,intposition){

}

@Override

publicvoidonItemLongClick(Viewview,intposition){

}

});

原理就是实现viewHolder.itemView的点击和长按事件。由于代码过多就不贴出来了。

viewHolder.itemView是RecyclerView.Adapter中本身就具有的,不用额外定义。

源码如下:

publicstaticabstractclassViewHolder{

publicfinalViewitemView;

intmPosition=NO_POSITION;

intmOldPosition=NO_POSITION;

longmItemId=NO_ID;

intmItemViewType=INVALID_TYPE;

intmPreLayoutPosition=NO_POSITION;

设置空白View(setEmptyView)

mRecyclerView.setEmptyView(view);

注意布局文件:

<RelativeLayout

xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="match_parent"

>

<com.cundong.recyclerview.LRecyclerView

android:id="@+id/list"

android:layout_width="fill_parent"

android:layout_height="fill_parent"/>

<include

android:id="@+id/empty_view"

layout="@layout/layout_empty"

android:visibility="gone"/>

</RelativeLayout>

分享

介绍完了LRecyclerView,似乎还少些什么,对了,那就是adapter了。

为了方便大家使用,分享个封装过的adapter。

publicclassListBaseAdapter<TextendsEntity>extendsRecyclerView.Adapter{

protectedContextmContext;

protectedintmScreenWidth;

publicvoidsetScreenWidth(intwidth){

mScreenWidth=width;

}

protectedArrayList<T>mDataList=newArrayList<>();

@Override

publicRecyclerView.ViewHolderonCreateViewHolder(ViewGroupparent,intviewType){

returnnull;

}

@Override

publicvoidonBindViewHolder(RecyclerView.ViewHolderholder,intposition){

}

@Override

publicintgetItemCount(){

returnmDataList.size();

}

publicList<T>getDataList(){

returnmDataList;

}

publicvoidsetDataList(Collection<T>list){

this.mDataList.clear();

this.mDataList.addAll(list);

notifyDataSetChanged();

}

publicvoidaddAll(Collection<T>list){

intlastIndex=this.mDataList.size();

if(this.mDataList.addAll(list)){

notifyItemRangeInserted(lastIndex,list.size());

}

}

publicvoidclear(){

mDataList.clear();

notifyDataSetChanged();

}

}

ListBaseAdapter使用了泛型,简单方便,消除了强制类型转换。

使用如下:

privateclassDataAdapterextendsListBaseAdapter<ItemModel>{

privateLayoutInflatermLayoutInflater;

publicDataAdapter(Contextcontext){

mLayoutInflater=LayoutInflater.from(context);

mContext=context;

}

@Override

publicRecyclerView.ViewHolderonCreateViewHolder(ViewGroupparent,intviewType){

returnnewViewHolder(mLayoutInflater.inflate(R.layout.sample_item_text,parent,false));

}

@Override

publicvoidonBindViewHolder(RecyclerView.ViewHolderholder,intposition){

ItemModelitem=mDataList.get(position);

ViewHolderviewHolder=(ViewHolder)holder;

viewHolder.textView.setText(item.title);

}

privateclassViewHolderextendsRecyclerView.ViewHolder{

privateTextViewtextView;

publicViewHolder(ViewitemView){

super(itemView);

textView=(TextView)itemView.findViewById(R.id.info_text);

}

}

}

ListBaseAdapter虽然功能不强大,但是使用很方便。

结语

LRecyclerView使用方便简单,无论你添加多少Header和Footer,你都不用担心position的问题,除了方便还是方便。大家用起来吧!

相关推荐