浅谈Android LRecyclerView

来源:互联网 发布:java模拟器安卓版官网 编辑:程序博客网 时间:2024/06/10 17:29

由于Recyclerview已经推出很长时间了,不得不说这个控件确实好,可以替代scrollview、listview、gridview,功能很强大,目前我已经用这个新控件实现了标题栏渐变的效果。

  • 简介

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

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

  • 主要功能
  • 下拉刷新、滑动到底部自动加载下页数据;
  • 可以方便添加Header和Footer;
  • 头部下拉样式可以自定义;
  • 具备item点击和长按事件。
  • 网络错误加载失败点击Footer重新请求数据;
  • 可以动态为FooterView赋予不同状态(加载中、加载失败、滑到最底等)。

  • 效果图

  • 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.2.9'

使用

  • 填充数据
mDataAdapter = new DataAdapter(this);mDataAdapter.setData(dataList);mLRecyclerViewAdapter = new LRecyclerViewAdapter(this, mDataAdapter);mRecyclerView.setAdapter(mLRecyclerViewAdapter);

1.DataAdapter是用户自己真正的adapter,用户自己定义;
2.LRecyclerViewAdapter提供了一些实用的功能,使用者不用关心它的实现,只需构造的时候把自己的mDataAdapter以参数形式传进去即可

  • 添加HeaderView、FooterView
//add a HeaderViewRecyclerViewUtils.setHeaderView(mRecyclerView, new SampleHeader(this));//add a FooterViewRecyclerViewUtils.setFooterView(mRecyclerView, new SampleFooter(this));
  • 下拉刷新和加载更多

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

mRecyclerView.setLScrollListener(new LRecyclerView.LScrollListener() {            @Override            public void onScrollUp() {            }            @Override            public void onScrollDown() {            }            @Override            public void onScrolled(int distanceX, int distanceY)       {            }            @Override            public void onScrollStateChanged(int state) {            }        });

LScrollListener实现了onScrollUp()、onScrollDown()、onScrolled、onScrollStateChanged四个事件,如下所示:

void onScrollUp();//scroll down to upvoid onScrollDown();//scroll from up to downvoid onScrolled(int distanceX, int distanceY);// moving state,you can get the move distancevoid onScrollStateChanged(int state);
  1. onScrollUp()——RecyclerView向上滑动的监听事件;

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

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

  4. onScrollStateChanged——RecyclerView滑动到状态监听;

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

mRecyclerView.setOnLoadMoreListener(new OnLoadMoreListener() {            @Override            public void onLoadMore() {            }        });
  • 下拉刷新

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

mRecyclerView.setOnRefreshListener(new OnRefreshListener() {            @Override            public void onRefresh() {            }        });
  • 效果图:
  • 下拉刷新逻辑处理:

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

根据大家的反馈,增加了一个强制刷新的方法,使用如下:

mRecyclerView.forceToRefresh();

无论是下拉刷新还是强制刷新,刷新完成后调用下面代码:

mRecyclerView.refreshComplete();mLRecyclerViewAdapter.notifyDataSetChanged();
  • 加载网络异常处理

加载数据时如果网络异常或者断网,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();        }    };
  • 点击事件和长按事件处理

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

Click and LongClick

不过一个挺郁闷的地方就是,系统没有提供ClickListener和LongClickListener。
不过我们也可以自己去添加,只是会多了些代码而已。
实现的方式比较多,你可以通过mRecyclerView.addOnItemTouchListener去监听然后去判断手势, 当然你也可以通过adapter中自己去提供回调,这里我们选择后者,前者的方式,大家有兴趣自己去实现。
先看下怎么使用:

mLRecyclerViewAdapter.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.github.jdsjlzx.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<T> 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<T> getDataList() {        return mDataList;    }    public void setDataList(Collection<T> list) {        this.mDataList.clear();        this.mDataList.addAll(list);        notifyDataSetChanged();    }    public void addAll(Collection<T> list) {        int lastIndex = this.mDataList.size();        if (this.mDataList.addAll(list)) {            notifyItemRangeInserted(lastIndex, list.size());        }    }    public void clear() {        mDataList.clear();        notifyDataSetChanged();    }}

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

使用如下:

private class DataAdapter extends ListBaseAdapter<ItemModel>{        private LayoutInflater mLayoutInflater;        public DataAdapter(Context context) {            mLayoutInflater = LayoutInflater.from(context);            mContext = context;        }        @Override        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {            return new ViewHolder(mLayoutInflater.inflate(R.layout.sample_item_text, parent, false));        }        @Override        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {            ItemModel item = mDataList.get(position);            ViewHolder viewHolder = (ViewHolder) holder;            viewHolder.textView.setText(item.title);        }        private class ViewHolder extends RecyclerView.ViewHolder {            private TextView textView;            public ViewHolder(View itemView) {                super(itemView);                textView = (TextView) itemView.findViewById(R.id.info_text);            }        }    }

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

  • 结语

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

阅读全文
0 0
原创粉丝点击