浏览 818 次
锁定老帖子 主题:Android开发操作案例分享!
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2016-08-04
Android LRecyclerView 操作案例分享-实现下拉刷新、滑动到底部自动加载,一直想抽空写下这个开源项目www.lampbrother.net,但是各种原因没有抽时间,今天还是趁着工作间隙写下了这篇博客,与大家分享。 简介 LRecyclerView是支持addHeaderView、 addFooterView、下拉刷新、分页加载数据的RecyclerView。 它对 RecyclerView 控件进行了拓展,给RecyclerView增加HeaderView、FooterView,并且不需要对你的Adapter做任何修改。 主要功能 下拉刷新、滑动到底部自动加载下页数据; 可以方便添加Header和Footer; 头部下拉样式可以自定义; 具备item点击和长按事件。 网络错误加载失败点击Footer重新请求数据; 可以动态为FooterView赋予不同状态(加载中、加载失败、滑到最底等)。 感谢 如果我比别人看得远些,那是因为我站在巨人们的肩上。 (牛顿) 本开源控件是基于 HeaderAndFooterRecyclerView 开源项目而来,在原基础上进行了扩充。在此感谢兄弟连教育(www.lampbrother.net)的分享 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中自己去提供回调,这里我们选择后者,前者的方式,大家有兴趣自己去实现。 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<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的问题,除了方便还是方便。大家用起来吧! 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |