专栏名称: 安卓开发精选
伯乐在线旗下账号,分享安卓应用相关内容,包括:安卓应用开发、设计和动态等。
目录
相关文章推荐
开发者全社区  ·  某基金「偷吃」? ·  8 小时前  
开发者全社区  ·  惨!清北复交都要跑路了 ·  昨天  
开发者全社区  ·  北京五道口惊现钢铁小老头 ·  昨天  
开发者全社区  ·  男朋友和女领导的聊天记录 ·  3 天前  
开发者全社区  ·  突发:DeepSeek被封杀 ·  3 天前  
51好读  ›  专栏  ›  安卓开发精选

Android LRecyclerView 实现下拉刷新,滑动到底部自动加载更多

安卓开发精选  · 公众号  · android  · 2016-08-10 08:14

正文

(点击 上方公众号 ,可快速关注)


来源:伯乐在线专栏作者 - 一叶飘舟

链接:http://android.jobbole.com/84060/

点击 → 了解如何加入专栏作者


很想给大家分享这个开源项目,但是由于工作的关系,没有抽出空,但还是趁着工作间隙写下了这篇博客。


简介


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


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


主要功能


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

  2. 可以方便添加Header和Footer;

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

  4. 具备item点击和长按事件。

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

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


项目地址:https://github.com/jdsjlzx/LRecyclerView


感谢


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


本开源控件是基于 HeaderAndFooterRecyclerView 开源项目而来,在原基础上进行了扩充。在此感谢cundong作者(github地址:https://github.com/cundong)。


效果图



Gradle


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


allprojects {

repositories {

jcenter ()

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

}

}


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


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


使用


加HeaderView FooterView


mDataAdapter = new DataAdapter ( this );

mDataAdapter . setData ( dataList );

mHeaderAndFooterRecyclerViewAdapter = new HeaderAndFooterRecyclerViewAdapter ( this , mDataAdapter );

mRecyclerView . setAdapter ( mHeaderAndFooterRecyclerViewAdapter );

mRecyclerView . setLayoutManager ( new LinearLayoutManager ( this ));

//add a HeaderView

RecyclerViewUtils . setHeaderView ( mRecyclerView , new SampleHeader ( this ));

//add a FooterView

RecyclerViewUtils . setFooterView ( mRecyclerView , new SampleFooter ( this ));


注意:


mHeaderAndFooterRecyclerViewAdapter = new HeaderAndFooterRecyclerViewAdapter(this, mDataAdapter);


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


下拉刷新和加载更多


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


mRecyclerView . setLScrollListener ( new LRecyclerView . LScrollListener () {

@Override

public void onRefresh () {

}

@Override

public void onScrollUp () {

}

@Override

public void onScrollDown () {

}

@Override

public void onBottom () {

}

@Override

public void onScrolled ( int distanceX , int distanceY ) {

}

});


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


void onRefresh (); //pull down to refresh

void onScrollUp (); //scroll down to up

void onScrollDown (); //scroll from up to down

void onBottom (); //load next page

void onScrolled ( int distanceX , int distanceY ); // moving state,you can get the move distance


  • 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 );

private View . OnClickListener mFooterClick = new View . OnClickListener () {

@Override

public void onClick ( View v ) {

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

requestData ();

}

};


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


点击事件和长按事件处理


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


Click and LongClick


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

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

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


出自:http://blog.csdn.net/lmj623565791/article/details/45059587


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


先看下怎么使用:


mHeaderAndFooterRecyclerViewAdapter . setOnItemClickLitener ( new OnItemClickLitener () {

@Override

public void onItemClick ( View view , int position ) {

}

@Override

public void onItemLongClick ( View view , int position ) {

}

});


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


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


源码如下:


public static abstract class ViewHolder {

public final View itemView ;

int mPosition = NO_POSITION ;

int mOldPosition = NO_POSITION ;

long mItemId = NO_ID ;

int mItemViewType = INVALID_TYPE ;

int mPreLayoutPosition = 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。


public class ListBaseAdapter T extends Entity > extends RecyclerView . Adapter {

protected Context mContext ;

protected int mScreenWidth ;

public void setScreenWidth ( int width ) {

mScreenWidth = width ;

}

protected ArrayList mDataList = new ArrayList ();

@Override

public RecyclerView . ViewHolder onCreateViewHolder ( ViewGroup parent , int viewType ) {

return null ;

}

@Override

public void onBindViewHolder ( RecyclerView . ViewHolder holder , int position ) {

}

@Override

public int getItemCount () {

return mDataList . size ();

}

public List getDataList () {

return mDataList ;

}

public void setDataList ( Collection list ) {

this . mDataList . clear ();

this . mDataList . addAll ( list );

notifyDataSetChanged ();

}

public void addAll ( Collection list ) {

int lastIndex =







请到「今天看啥」查看全文


推荐文章
开发者全社区  ·  某基金「偷吃」?
8 小时前
开发者全社区  ·  惨!清北复交都要跑路了
昨天
开发者全社区  ·  北京五道口惊现钢铁小老头
昨天
开发者全社区  ·  男朋友和女领导的聊天记录
3 天前
开发者全社区  ·  突发:DeepSeek被封杀
3 天前
译言  ·  我们为什么如此无聊?
8 年前
麻醉学大查房  ·  【头条】围术期肾保护
8 年前