RecyclerView功能集封装
来源:互联网 发布:linux上安装redmine 编辑:程序博客网 时间:2024/05/29 15:46
如要了解功能实现,请运行app程序查看控制台日志和源代码!
* 源代码 : AcmenXD/RecyclerView
* apk下载路径 : RecyclerView.apk
依赖
- AndroidStudio
allprojects { repositories { ... maven { url 'https://jitpack.io' } } }
// Android系统提供的recyclerview-v7包 compile 'com.android.support:recyclerview-v7:25.0.0' compile 'com.github.AcmenXD:RecyclerView:1.4'
功能
v1.4 新增功能有:
- 支持多层级分组功能(支持垂直|水平布局)(支持LinearLayoutManager/GridLayoutManager/StaggeredGridLayoutManager)
- 优化item各种事件
- 特别说明:多层级分组的GroupHeadLayout&GroupItemLayout暂不支持Margin及Padding设置,显示效果会有影响
v1.3 新增功能有:
- 支持分组功能
- 支持分组头布局悬浮RecyclerView顶部功能
v1.0 支持功能如下
- 支持下拉刷新
- 支持LoadMore(上拉加载更多)
- 支持添加Header、Footer、Empty(头、尾、空)视图
- 支持一个Adapter自定义多种Item类型
- 简化RecyclerView.Adapter及ViewHolder的实现
- LoadMore 和 Empty支持点击回调
- Adapter链式调用,易读、易懂、易用
- 支持item事件:单击 & 长按 & 滑动删除 & 拖拽换位 & 侧滑菜单功能(事件无任何冲突)
- 此封装库未对RecyclerView进行任何更改,布局或代码中使用原生RecyclerView即可
使用 -> 以下代码 注释很详细、很重要很重要很重要!!!
- xml布局
// 定义下拉刷新控件SwipeRefreshLayout 及 RecyclerView列表控件<android.support.v4.widget.SwipeRefreshLayout android:id="@+id/srl" android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.v7.widget.RecyclerView android:id="@+id/rv" android:layout_width="match_parent" android:layout_height="wrap_content"/></android.support.v4.widget.SwipeRefreshLayout>
- 初始RecyclerView
/* * recyclerView 需设置布局管理器 * * 通常只需要一个管理器即可,由于演示代码,固配置了所有管理器 */RecyclerView rv = (RecyclerView) findViewById(R.id.rv);// 线性布局LinearLayoutManager manager1 = new LinearLayoutManager(this);// 网格布局 参数:1.上下文对象 2.设置 列/行 数GridLayoutManager manager2 = new GridLayoutManager(this, 3);// 瀑布流布局 参数:1.设置 列/行 数 2.横/纵 向排列StaggeredGridLayoutManager manager3 = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);// 设置管理器的 横/纵 向排列manager1.setOrientation(OrientationHelper.VERTICAL);manager2.setOrientation(OrientationHelper.VERTICAL);manager3.setOrientation(OrientationHelper.VERTICAL);// 将管理器绑定到recyclerViewrv.setLayoutManager(manager1);// 设置item之间的分隔线(默认提供三种分隔线,对应三种局部.如有其它需求,可自行实现)rv.addItemDecoration(new LinearLayoutDecoration(this));// rv.addItemDecoration(new GridLayoutDecoration(this));// rv.addItemDecoration(new StaggeredGridLayoutDecoration(this));// 设置增加或删除item项的动画rv.setItemAnimator(new DefaultItemAnimator());
下拉刷新
/** * 下载刷新用系统提供的SwipeRefreshLayout,并未使用PullToRefresh */SwipeRefreshLayout srl = (SwipeRefreshLayout) findViewById(R.id.srl);// 设置刷新控件转圈圈的动画颜色,每转一圈一个颜色srl.setColorSchemeColors(Color.RED, Color.GREEN, Color.BLUE);// 设置转圈圈的背景色srl.setProgressBackgroundColorSchemeColor(Color.YELLOW);// 设置转圈圈的大小,默认是DEFAULTsrl.setSize(SwipeRefreshLayout.DEFAULT);//SwipeRefreshLayout.LARGE// 参数:1.下拉圈圈是否缩放 2.圈圈下拉的高度srl.setProgressViewEndTarget(true, 200);// 设置刷新的事件监听器srl.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { datas.clear(); // 清理输出 addNewData(); // 添加新数据 refreshAdapter(); // 刷新Adapter srl.setRefreshing(false); // 关闭圈圈 }});
Adapter - 单类型Item
/** * 创建SimpleAdapter * 泛型:数据的类型 * 参数:1.上下文对象 2.recyclerview实例 3.item布局 4.数据集List */SimpleAdapter mAdapter = new SimpleAdapter<Data>(this, rv, R.layout.activity_recycler_item, datas) { @Override public void convert(ViewHolder viewHolder,Data item, int dataPosition) { // 刷新界面 viewHolder-控件集 item-数据 dataPosition-位置 // getView(rId)是viewHolder实现的方法,此方式获取控件无需再强转类型 TextView tv = viewHolder.getView(R.id.activity_recycler_item_tv); tv.setText(item.name); }};
Adapter - 多类型Item
/** * 创建MultiItemTypeAdapter * 泛型:数据的类型 * 参数:1.上下文对象 2.recyclerview实例 3.数据集List */MultiItemTypeAdapter mAdapter = new MultiItemTypeAdapter<Data>(this, rv, datas);// 添加一种item类型(有几种类型,添加几个)mAdapter.addItemViewDelegate(new ItemDelegate<Data>() { @Override public int getItemViewLayoutId() { // 此种类的item需要的布局文件 return R.layout.activity_recycler_item; } @Override public boolean isItemViewType(Data data, int dataPosition) { // 根据数据或位置判断是否用此种类型的item,返回bool类型 return data.type == 1; } @Override public void convert(ViewHolder viewHolder, Data data, int dataPosition) { // 刷新界面 viewHolder-控件集 item-数据 dataPosition-位置 // getView(rId)是viewHolder实现的方法,此方式获取控件无需再强转类型 TextView tv = viewHolder.getView(R.id.activity_recycler_item_tv); TextView tv_age = viewHolder.getView(R.id.activity_recycler_item_tv_age); TextView tv_type = viewHolder.getView(R.id.activity_recycler_item_tv_type); tv.setText(data.name); tv_age.setText("index:" + data.index); tv_type.setText("类型:" + data.type); }});// 添加第二种item类型(有几种类型,添加几个)mAdapter.addItemViewDelegate(new ItemDelegate<Data>() { @Override public int getItemViewLayoutId() { return R.layout.activity_recycler_item2; } @Override public boolean isItemViewType(Data data, int dataPosition) { return data.type == 2; } @Override public void convert(ViewHolder viewHolder, Data data, int dataPosition) { TextView tv = viewHolder.getView(R.id.activity_recycler_item_tv); TextView tv_age = viewHolder.getView(R.id.activity_recycler_item_tv_age); TextView tv_type = viewHolder.getView(R.id.activity_recycler_item_tv_type); tv.setText(data.name); tv_age.setText("index:" + data.index); tv_type.setText("类型:" + data.type); }});
Adapter - 单类型+侧滑菜单的Item
/** * 创建SimpleSwipeMenuAdapter * 泛型:数据的类型 * 参数:1.上下文对象 2.recyclerview实例 3.item布局 4.数据集List 5.侧滑菜单需要的监听器 */SimpleSwipeMenuAdapter mAdapter = new SimpleSwipeMenuAdapter<Data>(this, rv, R.layout.activity_recycler_item, datas, new OnSwipeMenuListener() { @Override public int[] getLeftMenuLayoutIds(int dataPosition) { // item左侧菜单(如不需要,return null即可) // 根据位置判断要显示的菜单布局及菜单项 if (dataPosition == 3) { // 返回一个数组new int[]{菜单布局,菜单项1,菜单项2,菜单项3} return new int[]{R.layout.activity_recycler_swipe_menu_right , R.id.menu_1, R.id.menu_2, R.id.menu_3}; } // 返回一个数组new int[]{菜单布局,菜单项1,菜单项2} return new int[]{R.layout.activity_recycler_swipe_menu_left , R.id.menu_1, R.id.menu_2}; } @Override public int[] getRightMenuLayoutIds(int dataPosition) { // 右侧菜单同左侧菜单(如不需要,return null即可) return new int[]{R.layout.activity_recycler_swipe_menu_right , R.id.menu_1, R.id.menu_2, R.id.menu_3}; } @Override public boolean onMenuItemClick(int dataPosition, int menuItemLayoutId, int direction) { // 菜单项点击回调 // 函数参数:1.dataPosition列表的位置 2.menuItemLayoutId菜单项Id 3.左/右测菜单 String dirStr = "左边菜单"; if (direction == SwipeMenuView.RIGHT_DIRECTION) { dirStr = "右边菜单"; } switch (menuItemLayoutId) { case R.id.menu_1: ToastUtils.show("position:" + dataPosition + dirStr + "的第一个menu"); break; case R.id.menu_2: ToastUtils.show("position:" + dataPosition + dirStr + "的第二个menu"); break; case R.id.menu_3: ToastUtils.show("position:" + dataPosition + dirStr + "的第三个menu"); break; } return true; }}) { @Override public void convert(ViewHolder viewHolder, Data item, int dataPosition) { // 刷新界面 viewHolder-控件集 item-数据 dataPosition-位置 }};
Adapter - 多类型+侧滑菜单的Item
/** * 创建MultiItemTypeSwipeMenuAdapter * 泛型:数据的类型 * 参数:1.上下文对象 2.recyclerview实例 3.数据集List 4.侧滑菜单需要的监听器 * 菜单创建和使用方式同上 : Adapter - 单类型+侧滑菜单的Item */mAdapter = new MultiItemTypeSwipeMenuAdapter(this, rv, datas, new OnSwipeMenuListener() { @Override public int[] getLeftMenuLayoutIds(int dataPosition) { return new int[0]; } @Override public int[] getRightMenuLayoutIds(int dataPosition) { return new int[0]; } @Override public boolean onMenuItemClick(int dataPosition, int menuItemLayoutId, int direction) { return false; }});// 添加一种item类型(有几种类型,添加几个)mAdapter.addItemViewDelegate(new ItemDelegate<Data>() {});// 添加第二种item类型(有几种类型,添加几个)mAdapter.addItemViewDelegate(new ItemDelegate<Data>() {});
Header、Footer视图
/* * 创建HeaderAndFooterWrapper * 参数:1.recyclerview实例 2.Adapter实例(链式Adapter,最底层为RecyclerView.Adapter,其次为自定义Wrapper) */HeaderAndFooterWrapper mHeaderAndFooterWrapper = new HeaderAndFooterWrapper(rv, mAdapter);// HeaderView1TextView t1 = new TextView(this);t1.setText("Header 1\n\nHeader 1");// HeaderView2TextView t2 = new TextView(this);t2.setText("Header 2\n\nHeader 2");// HeaderView添加到列表中mHeaderAndFooterWrapper.addHeaderView(t1);mHeaderAndFooterWrapper.addHeaderView(t2);// FooterView1TextView t3 = new TextView(this);t3.setText("Footer 1\n\nFooter 1");// FooterView2TextView t4 = new TextView(this);t4.setText("Footer 2\n\nFooter 2");// FooterView添加到列表中mHeaderAndFooterWrapper.addFootView(t3);mHeaderAndFooterWrapper.addFootView(t4);
Empty视图
/* * 创建EmptyWrapper * 参数:1.recyclerview实例 2.Adapter实例(链式Adapter,最底层为RecyclerView.Adapter,其次为自定义Wrapper) 3.EmptyView 4.Empty视图点击事件监听器 */// EmptyViewTextView t6 = new TextView(this);t6.setText("无数据,点击加载\n\n无数据,点击加载");EmptyWrapper mEmptyWarpper = new EmptyWrapper(rv, mHeaderAndFooterWrapper, t6, new OnEmptyListener() { @Override public void onEmptyClick(View itemView) { // 点击回调 loadMore(itemView); }});
上拉加载更多
/* * 创建LoadMoreWrapper * 参数:1.recyclerview实例 2.Adapter实例(链式Adapter,最底层为RecyclerView.Adapter,其次为自定义Wrapper) 3.LoadMore视图点击事件监听器 * 支持自定义LoadMore视图 */LoadMoreWrapper mLoadMoreWarpper = new LoadMoreWrapper(rv, mHeaderAndFooterWrapper, new OnLoadMoreListener() { @Override public void onLoadMore(View itemView) { // 上拉加载更多回调 loadMore(itemView); } @Override public void onLoadMoreClick(View itemView) { // LoadMore单击回调 loadMore(itemView); }});// 提前2条加载下一次数据mLoadMoreWarpper.setRefreshBefore(2);
事件监听器(单击&长按 & 滑动删除 & 拖拽变换)
/* * 需创建AddItemListener统一管理各个监听器,避免出现各事件冲突 * 如不需要实现的功能,监听器可以传null * 参数:1.recyclerview实例 2.单击&长按 监听 3.滑动删除 监听 4.拖拽变换 监听 */new AddItemListener(rv, new ItemCallback() { @Override public void onClick(RecyclerView.ViewHolder viewHolder, int dataPosition) { // 单击回调 ToastUtils.show("item:" + dataPosition); } @Override public void onLongClick(RecyclerView.ViewHolder viewHolder, int dataPosition) { //长按回调 ToastUtils.show("longClick:" + dataPosition); }}, new ItemSwipeCallback() { @Override public boolean onDeleteData(RecyclerView.ViewHolder viewHolder, int dataPosition, int viewPosition) { // 滑动删除回调,需手动处理数据 datas.remove(dataPosition); // 返回值:true表示自动删掉item视图 false表示要手动处理视图 return true; } @Override public boolean onDeleteCheck(RecyclerView.ViewHolder viewHolder, int dataPosition) { // 返回值:true表示此item项支持侧滑删除功能 false表示不支持侧滑删除 if (dataPosition < 5) { return false; } return super.onDeleteCheck(viewHolder, dataPosition); }}, new ItemDragCallback() { @Override public boolean onTransformData(RecyclerView.ViewHolder fromViewHolder, RecyclerView.ViewHolder toViewHolder, int fromDataPosition, int toDataPosition, int fromViewPosition, int toViewPosition) { // 变换回调,需手动处理数据(变换数据位置) datas.add(toDataPosition, datas.remove(fromDataPosition)); // 返回值:true表示自动删掉并添加item视图 false表示要手动处理视图 return true; } @Override public boolean onTransformCheck(RecyclerView.ViewHolder viewHolder, int dataPosition) { // 返回值:true表示此item项支持长按拖动功能 false表示不支持长按拖动功能 // 此回调为起始位回调,非被换位置的item项 if (dataPosition < 2) { return false; } return super.onTransformCheck(viewHolder, dataPosition); } @Override public boolean onTransformToCheck(RecyclerView.ViewHolder viewHolder, int dataPosition) { // 返回值:true表示此item项允许被换位置 false表示不允许 if (dataPosition < 2) { return false; } return super.onTransformToCheck(viewHolder, dataPosition); } @Override public void onSelectedStart(RecyclerView.ViewHolder viewHolder) { // 拖动开始生效时回调 viewHolder.itemView.setBackgroundColor(Color.LTGRAY); } @Override public void onSelectedEnd(RecyclerView.ViewHolder viewHolder) { // 拖动结束时回调 viewHolder.itemView.setBackgroundResource(0); }});
分组 + 悬浮
/* * 创建分组回调监听 */GroupListener mGroupListener = new GroupListener() { /** * 获取GroupItem层级的数量 */ @Override public int getGroupItemLevelNum() { return 4; } /** * 判断GroupItem的视图类型是否大于一种(当Level等级大于1时,此值不在有效) */ @Override public boolean isGroupItemTypeMoreOne() { return false; } /** * 设置Head是否自动与GroupItemView宽高同步 */ @Override public boolean isAutoSetGroupHeadViewWidthHeightByGroupItemView() { return false; } /** * 判断是否创建GroupItemView * @param dataPosition 定位数据的position */ @Override public boolean isCreateGroupItemView(int dataPosition) { if (datas.get(dataPosition).type == 3) { return true; } return false; } /** * 获取GroupItemView视图 * @param root 容器 * @param groupLevel 分组层级(计数从0开始) * @param dataPosition 定位数据的position */ @Override public View getGroupItemView(ViewGroup root, int groupLevel, int dataPosition) { View view = null; if (datas.get(dataPosition).type == 3) { if (dataPosition % 15 == 0) { switch (groupLevel) { case 0: view = LayoutInflater.from(MainActivity.this).inflate(R.layout.activity_recycler_group_item, root, false); break; case 1: view = LayoutInflater.from(MainActivity.this).inflate(R.layout.activity_recycler_group_item2, root, false); break; case 2: view = LayoutInflater.from(MainActivity.this).inflate(R.layout.activity_recycler_group_item3, root, false); break; case 3: view = LayoutInflater.from(MainActivity.this).inflate(R.layout.activity_recycler_group_item4, root, false); break; } } else { switch (groupLevel) { case 1: view = LayoutInflater.from(MainActivity.this).inflate(R.layout.activity_recycler_group_item2, root, false); break; case 2: view = LayoutInflater.from(MainActivity.this).inflate(R.layout.activity_recycler_group_item3, root, false); break; case 3: view = LayoutInflater.from(MainActivity.this).inflate(R.layout.activity_recycler_group_item4, root, false); break; } } } return view; } /** * 更新GroupItemView视图 * @param groupItemView 要更新的groupItemView * @param groupLevel 分组层级(计数从0开始) * @param dataPosition 定位数据的position */ @Override public void changeGroupItemView(View groupItemView, int groupLevel, int dataPosition) { TextView tv = (TextView) groupItemView.findViewById(R.id.activity_recycler_group_item_tv_number); tv.setText("dataPosition:" + dataPosition + " groupLevel:" + groupLevel); } /** * 获取GroupHeadView视图 * * 大多数情况下与GroupItemView相同,可互相调用(保留此回调是为了当出现于GroupHeadView不同时,方便拓展) * @param root 容器 * @param groupLevel 分组层级(计数从0开始) * @param dataPosition 定位数据的position */ @Override public View getGroupHeadView(ViewGroup root, int groupLevel, int dataPosition) { return getGroupItemView(root, groupLevel, dataPosition); } /** * 更新GroupHeadView视图 * * 大多数情况下与GroupItemView相同,可互相调用(保留此回调是为了当出现于GroupHeadView不同时,方便拓展) * @param groupHeadView 要更新的groupHeadView * @param groupLevel 分组层级(计数从0开始) * @param dataPosition 定位数据的position */ @Override public void changeGroupHeadView(View groupHeadView, int groupLevel, int dataPosition) { changeGroupItemView(groupHeadView, groupLevel, dataPosition); }};/** * 创建分组Decoration并设置布局,添加到RecyclerView中,并绑定GroupListener */rv.addItemDecoration(new GroupDecoration((GroupHeadLayout) findViewById(R.id.groupLayout), mGroupListener));/** * 如果RecyclerView为GridLayoutManager或StaggeredGridLayoutManager,则必须设置 * 兼容Group分组功能,网格或瀑布流,必须设置,否则无法支持Group功能 */mAdapter.setGroupListener(mGroupListener);
打个小广告^_^
gitHub : https://github.com/AcmenXD 如对您有帮助,欢迎点Star支持,谢谢~
技术博客 : http://blog.csdn.net/wxd_beijing
END
1 0
- RecyclerView功能集封装
- recyclerview封装
- RecyclerView封装
- RecyclerView封装
- 封装RecyclerView,实现下拉刷新,上拉加载功能
- RecyclerView+SwipeRefreshLayou封装下拉刷新,上拉加载功能
- 对RecyclerView的封装,使用简单,功能丰富
- RecyclerView再封装
- 封装RecyclerView.ViewHolder
- 封装RecyclerView.Adapter
- RecyclerView Adapter 封装
- android recyclerview adaper封装
- simple封装RecyclerView.Adapter
- Android Recyclerview的封装
- RecyclerView 的简单封装
- RecyclerView Adapter简单封装
- 业余时间:RecyclerView的封装
- RecyclerView Adapter 封装
- 排序算法(四):JAVA实现希尔排序
- Altium Designer如何画虚线
- mysql5.7 linux下64位安装
- java中volatile关键字的含义
- 前端开发不得不知道的十大ES6新特性
- RecyclerView功能集封装
- 常用的SQL语句
- Brute Force匹配(暴力匹配)和FLANN匹配区别
- Linux书籍
- 133
- Linux常见函数的区别
- Machine Learning in Action | ApacheCN(apache中文网)
- Groovy学习
- ManualResetEvent详解