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
原创粉丝点击