BaseRecyclerViewAdapterHelper的使用

BaseRecyclerViewAdapterHelper的使用

BaseRecyclerViewAdapterHelper是一个强大且灵活的RecyclerViewAdapter,那么它都能做什么呢?

  • 可以大量减少Adapter中的代码(对于多类型数据,需要写ViewHolder,只需要写多个bean类即可);
  • 可以定义一个多类型的 MultiesAdapter替代多个adapter使用;
  • 可以很轻松的添加RecyclerView加载动画;
  • 添加头部、添加尾部;
  • 支持下拉刷新、上拉加载更多(作为条目填充);
  • 支持分组(Section,可以看成是多类型条目的一种,有两种类型);
  • 支持自定义item类型;
  • 支持setEmptyView;
  • 可以添加item点击事件;
  • 支持子布局多个控件的点击事件;
好的,接下来我们直接来谈其配置和使用:

在 build.gradle 的 repositories 添加:

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

然后增加dependencies

dependencies {
    compile 'com.github.CymChad:BaseRecyclerViewAdapterHelper:v1.9.7'
}
这里需要说明一下,依赖的BaseRecyclerViewAdapterHelper不同,会导致方法使用上是有差别的,下边提供其他依赖:
'compile 'com.github.CymChad:BaseRecyclerViewAdapterHelper:v1.5.8'
'compile 'com.github.CymChad:BaseRecyclerViewAdapterHelper:v1.5'

1,单类型BaseQuickAdapter使用
public class MyQuickAdapter extends BaseQuickAdapter implements View.OnClickListener,View.OnLongClickListener{
    public MyQuickAdapter(int layoutResId, List data) {
        super(layoutResId, data);
    }
    public MyQuickAdapter(List data) {
        super(data);
    }
    public MyQuickAdapter(View contentView, List data) {
        super(contentView, data);
    }
    @Override
    protected void convert(BaseViewHolder baseViewHolder,  MultyItemBean multyItemBean) {
        baseViewHolder.setText(R.id.content_tv, multyItemBean.content)
                .setChecked(R.id.checkbox_content,multyItemBean.checked)
                .setOnClickListener(R.id.content_tv,this)
                //设置item中某个控件的长点击事件监听,而.setOnItemClickListener()是设置整个条目的点击监听的
                .setOnLongClickListener(R.id.content_tv,this);
//        this.setOnRecyclerViewItemClickListener();
//        this.setOnRecyclerViewItemChildClickListener(listener);
//        this.setOnRecyclerViewItemLongClickListener(listener2);
    }
    @Override
    public void onClick(View view) {
        if (view.getId() == R.id.content_tv) {
            Toast.makeText(Myapp.context, "Item中某个控件被点击了", Toast.LENGTH_SHORT).show();
        }
    }
    @Override
    public boolean onLongClick(View view) {
        if (view.getId() == R.id.content_tv) {
            Toast.makeText(Myapp.context, "Item中某个控件被长按了", Toast.LENGTH_SHORT).show();
        }
        return true;
    }
}

Activity中代码:
quickAdapter = new MyQuickAdapter(R.layout.adapter_content, data);//单类型的item布局是放在构造中的,而多类型用的是方法

动画添加, 有3种方式:
//        multyItemAdapter.openLoadAnimation();  //默认为渐显效果
        dragAndSwipAdater.isFirstOnly(false); //设置不仅是首次填充数据时有动画,以后上下滑动也会有动画
        //有5种动画可以设置,但若是多类型数据时,可能只有第一种类型(第0ViewType)数据有动画效果,也许被看成了单类型了
        dragAndSwipAdater.openLoadAnimation(BaseMultiItemQuickAdapter.SLIDEIN_LEFT);
//        multyItemAdapter.openLoadAnimation(new BaseAnimation() { //自定义动画
//            @Override
//            public Animator[] getAnimators(View view) {
//                return new Animator[]{
//                    ObjectAnimator.ofFloat(view, "scaleY", 0.3f, 5f, 1),
//                    ObjectAnimator.ofFloat(view, "scaleX", 0.3f, 8f, 1),
//                    ObjectAnimator.ofFloat(view, "rotation", 1, 60, 0)
//                };
//            } 


系统默认的5种动画如下:
 public static final int ALPHAIN = 1;  
 public static final int SCALEIN = 2;  
 public static final int SLIDEIN_BOTTOM = 3;  
 public static final int SLIDEIN_LEFT = 4;  
 public static final int SLIDEIN_RIGHT = 5; 

添加header,footer:

mQuickAdapter.addHeaderView(getView());
mQuickAdapter.addFooterView(getView());

加载更多设置:

mQuickAdapter.setOnLoadMoreListener(PAGE_SIZE, new BaseQuickAdapter.RequestLoadMoreListener() {
            @Override
            public void onLoadMoreRequested() {
                if (mCurrentCounter >= TOTAL_COUNTER) {
                    mRecyclerView.post(new Runnable() {
                        @Override
                        public void run() {
                            mQuickAdapter.isNextLoad(false);
                        }
                    });
                } else {
                    // reqData
                    mCurrentCounter = mQuickAdapter.getItemCount();
                    mQuickAdapter.isNextLoad(true);
                }
            }
        });
2,多类型BaseMultiItemQuickAdapter的用法:
/**
 * 这种Adapter类可以直接在Activity中用匿名内部类方式实现,这样就不用创建不同的adapter了,
 * 以后可以只用这一个MyMultitypeItemAdapter给多个界面的RecyclerView,只要设置addItemType()
 * 和不同的bean即可,无需设置holder
 */
public class MyMultitypeItemAdapter extends BaseMultiItemQuickAdapter implements View.OnClickListener,View.OnLongClickListener{
    public MyMultitypeItemAdapter(List data) {
        super(data);
        addItemType(0, R.layout.adapter_title);  //必须设置Item类型,否则空职指针异常
        addItemType(1,R.layout.adapter_content);
    }
    @Override
    protected void convert(BaseViewHolder baseViewHolder, MultyItemBean multyItemBean) {
        switch (multyItemBean.getItemType()) {  //或采用baseViewHolder.getItemViewType()方式
            case 0: //标题:
                baseViewHolder.setText(R.id.tv_title, multyItemBean.content);
                break;
            case 1: //内容
                baseViewHolder.setChecked(R.id.checkbox_content, multyItemBean.checked);
                baseViewHolder.setText(R.id.content_tv, multyItemBean.content)
                        .setChecked(R.id.checkbox_content,multyItemBean.checked)
                        .setOnClickListener(R.id.content_tv,this)
                        //设置item中某个控件的长点击事件监听,而.setOnItemClickListener()是设置整个条目的点击监听的
                        .setOnLongClickListener(R.id.content_tv,this);
                break;
        }
    }

3,分组BaseSectionQuickAdapter:
public class MySectionAdapter extends BaseSectionQuickAdapter {

    public MySectionAdapter(int layoutResId, int sectionHeadResId, List data) {
        super(layoutResId, sectionHeadResId, data);
    }
    @Override
    protected void convertHead(BaseViewHolder helper, Section_titileBean bean) {
        //下边的两种方式效果相同,bean.isHeader==false时,TextView不会被赋值
        helper.setText(R.id.section_header, bean.header);
//        if (bean.isHeader) {
//            helper.setText(R.id.section_header, bean.header);
//        }else {
//            helper.setText(R.id.section_header, bean.header);
//        }
    }
    @Override
    protected void convert(BaseViewHolder helper, Section_titileBean bean) {
        helper.setText(R.id.section_content, bean.t);
    }
}
注意:在使用的时候,bean数据类必须继承 MultiItemEntity或SectionEntity

使用setEmptyView:

mQuickAdapter.setEmptyView(getView());

添加子布局多个控件的点击事件:

    Adapter

protected void convert(BaseViewHolder helper, Status item) {
    helper.setOnClickListener(R.id.tweetAvatar, new OnItemChildClickListener())
      .setOnClickListener(R.id.tweetName, new OnItemChildClickListener());
}

Activity

mQuickAdapter.setOnRecyclerViewItemChildClickListener(new BaseQuickAdapter.OnRecyclerViewItemChildClickListener() {
            @Override
            public void onItemChildClick(BaseQuickAdapter adapter, View view, int position) {
                String content = null;
                Status status = (Status) adapter.getItem(position);
                switch (view.getId()) {
                    case R.id.tweetAvatar:
                        content = "img:" + status.getUserAvatar();
                        break;
                    case R.id.tweetName:
                        content = "name:" + status.getUserName();
                        break;
                }
                Toast.makeText(AnimationUseActivity.this, content, Toast.LENGTH_LONG).show();
            }
        });
4,实现拖拽BaseItemDraggableAdapter:
/**
 * 暂时该侧滑删除功能的adapter只测试了单类型的数据填充,但可用于多种LayoutManager情况
 */
public class DragAndSwipAdater extends BaseItemDraggableAdapter {

    public DragAndSwipAdater(View contentView, List data) {
        super(contentView, data);
    }
    public DragAndSwipAdater(List data) {
        super(R.layout.adapter_title,data);
    }
    public DragAndSwipAdater(int layoutResId, List data) {
        super(layoutResId, data);
    }
    @Override
    protected void convert(BaseViewHolder baseViewHolder, MultyItemBean multyItemBean) {
        baseViewHolder.setText(R.id.tv_title,"DragAndSwipItem: " + multyItemBean.content);
    }
}

Activity的全部代码:
public class RecyclerViewActivity extends BaseActivity implements Toolbar.OnMenuItemClickListener,BaseQuickAdapter.RequestLoadMoreListener{
    @Bind(R.id.recyclerview)
    RecyclerView recyclerview;
    @Bind(R.id.swipe_recycle_lt)
    SwipeRefreshLayout swipeRecycleLt;
    private RecycleBean bean;
    private List contentListT;
    private String[] titles;
    private ArrayList contentListCBox;
    private ReAdapter reAdapter;
    private MyQuickAdapter quickAdapter;
    private ArrayList data;
    private List sectionData;
    private MyMultitypeItemAdapter multyItemAdapter;
    private OnItemDragListener onItemDragListener;
    private OnItemSwipeListener onItemSwipeListener;
    private DragAndSwipAdater dragAndSwipAdater;
    private int mError = 0;
    private int mNoData = 1;
    private int dataStatu = 1;
    private MySectionAdapter sectionAdapter;

    @Override
    protected void initView() {
        //Toobar的使用需要先fvb到Toobar布局,然后在MenuInflate到menu布局,同时给toobar设置点击监听
        Toolbar toolBar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolBar);
        toolBar.setTitle("ToolBarTitle");//设置标题
        toolBar.setNavigationIcon(R.mipmap.ic_launcher);//设置图标
        toolBar.setOnMenuItemClickListener(this);//设置Menu Item点击
    }

    @Override
    protected void initData() {
        //设置SwipeRefreshLayout刷新样式,颜色可以设置5种以上
        swipeRecycleLt.setColorSchemeColors(Color.RED, Color.BLUE, Color.GREEN,Color.BLACK,Color.YELLOW);
        //数据准备
        bean = new RecycleBean();
        data = new ArrayList();
        sectionData = new ArrayList<>();
        contentListT = new ArrayList();
        contentListCBox = new ArrayList();
        titles = new String[60];
        for (int i = 0; i < 30; i++) {
            contentListT.add(i);
            data.add(new MultyItemBean(true, String.valueOf(i),1));
            sectionData.add(new Section_titileBean(true,"header "+i));
            sectionData.add(new Section_titileBean(false,"is not header "+i));//isHeader==false时,TextView不会被赋值
            sectionData.add(new Section_titileBean("others "+i));
            titles[i] = "我是title: " + i;
            contentListCBox.add(false);
        }
        bean.contentListCBox = contentListCBox;
        bean.contentListT = contentListT;
        bean.titles = titles;

        configurateRecyclerView(); //对RecyclerView进行各种效果配置

//        quickAdapter.addData(data);//数据的添加,并自动刷新数据(方式一)
        data.add(3, new MultyItemBean(false, "我是被改变的类型一", 0));//数据的添加,并自动刷新数据(方式二)
        data.add(6, new MultyItemBean(false, "我是被改的类型二", 1));
//        quickAdapter.notifyItemInserted(1);//或者采用下边局部的刷新刷新方式
        dragAndSwipAdater.notifyItemRangeInserted(1,7);
    }

    private void configurateRecyclerView() {
        //LayoutManager设置
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, OrientationHelper.VERTICAL, false);
        GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 3, OrientationHelper.VERTICAL, false);
        StaggeredGridLayoutManager sglm = new StaggeredGridLayoutManager(4, OrientationHelper.VERTICAL);

        //RecyclerView的adapter设置
        reAdapter = new ReAdapter(this, bean); //RecyclerView的baseAdapter
        //因为该adapter只用于单一类型holder,所以在设计时,在构造中就填入holder的view的id,而用于多类型的adapter则需要方法填充
        quickAdapter = new MyQuickAdapter(R.layout.adapter_content, data);
        multyItemAdapter = new MyMultitypeItemAdapter(data);//多类型条目
        sectionAdapter = new MySectionAdapter(R.layout.section_content_adapgter, R.layout.section_header_adapgter, sectionData);
        dragAndSwipAdater = new DragAndSwipAdater(data); //可拖拽和删除类型

        //给Adapter设置拖拽和侧滑删除
        doDragAndSwipDelate();

        //添加footer和heander
        dragAndSwipAdater.addHeaderView(getView(R.layout.refresh_header));//无监听效果,可以考虑放轮播图
        dragAndSwipAdater.addFooterView(getView(R.layout.refresh_footer));
        dragAndSwipAdater.setLoadingView(getView(R.layout.refresh_footer)); //设置了addFooterView()才能y9ong此法修改footerView
        dragAndSwipAdater.openLoadMore(40,true); //默认使用自己的footerView,更改的话需要先设置addFooterView(),然后在设置multyItemAdapter.setLoadingView(footerView)
        dragAndSwipAdater.setOnLoadMoreListener(this); //我测试时不起作用
//        dragAndSwipAdater.setAutoLoadMoreSize(3);

        //添加分割线
        recyclerview.addItemDecoration(new DividerGridItemDecoration(this));
//        recyclerview.addItemDecoration(new RecycleLinearItemDecoration(this,RecycleLinearItemDecoration.VERTICAL_LIST));

        //Item增删动画设置
//        recyclerview.setItemAnimator(new DefaultItemAnimator());//添加默认Item增删动画而非初始化时的动画
//        multyItemAdapter.openLoadAnimation();  //默认为渐显效果
        dragAndSwipAdater.isFirstOnly(false); //设置不仅是首次填充数据时有动画,以后滑动也会有动画
        //有5种动画可以设置,但若是多类型数据时,可能只有第一种类型(第0ViewType)数据有动画效果,也许被看成了单类型了
        dragAndSwipAdater.openLoadAnimation(BaseMultiItemQuickAdapter.SLIDEIN_LEFT);
//        multyItemAdapter.openLoadAnimation(new BaseAnimation() { //自定义动画
//            @Override
//            public Animator[] getAnimators(View view) {
//                return new Animator[]{
//                    ObjectAnimator.ofFloat(view, "scaleY", 0.3f, 5f, 1),
//                    ObjectAnimator.ofFloat(view, "scaleX", 0.3f, 8f, 1),
//                    ObjectAnimator.ofFloat(view, "rotation", 1, 60, 0)
//                };
//            }
//        });

        recyclerview.setHasFixedSize(true); //保存item尺寸值,以便不在测量
        //RecyclerView的配置
        recyclerview.setLayoutManager(gridLayoutManager);
        recyclerview.setAdapter(dragAndSwipAdater);
    }

    private void doDragAndSwipDelate() {
        //拖拽监听
        onItemDragListener = new OnItemDragListener() {
            @Override
            public void onItemDragStart(RecyclerView.ViewHolder viewHolder, int pos){}
            @Override
            public void onItemDragMoving(RecyclerView.ViewHolder source, int from, RecyclerView.ViewHolder target, int to) {}
            @Override
            public void onItemDragEnd(RecyclerView.ViewHolder viewHolder, int pos) {}
        };

        //侧滑删除监听
        onItemSwipeListener = new OnItemSwipeListener() {
            @Override
            public void onItemSwipeStart(RecyclerView.ViewHolder viewHolder, int pos) {}
            @Override
            public void onItemSwipeMoving(Canvas canvas, RecyclerView.ViewHolder viewHolder, float v, float v1, boolean b) {
                //设置滑动过程中划出部分的填补颜色
                canvas.drawColor(ContextCompat.getColor(RecyclerViewActivity.this, R.color.colorAccent));
            }
            @Override
            public void onItemSwiped(RecyclerView.ViewHolder viewHolder, int pos) {
            }
            @Override
            public void clearView(RecyclerView.ViewHolder viewHolder, int pos) {
            }
        };

        ItemDragAndSwipeCallback itemDragAndSwipeCallback = new ItemDragAndSwipeCallback(dragAndSwipAdater);
        ItemTouchHelper itemTouchHelper = new ItemTouchHelper(itemDragAndSwipeCallback);
        itemTouchHelper.attachToRecyclerView(recyclerview);
        itemDragAndSwipeCallback.setSwipeMoveFlags(ItemTouchHelper.START | ItemTouchHelper.END);//设置双向滑动功能

         //开启长按拖拽功能
        dragAndSwipAdater.enableDragItem(itemTouchHelper);
        dragAndSwipAdater.setOnItemDragListener(onItemDragListener);

        // 开启滑动删除功能
        dragAndSwipAdater.enableSwipeItem();
        //若不做特殊处理,可以不设置滑动或拖拽监听,其自动能实现拖拽或删除功能了
        dragAndSwipAdater.setOnItemSwipeListener(onItemSwipeListener);
    }

    private View getView(int viewId) {
        return LayoutInflater.from(this).inflate(viewId, new RelativeLayout(this));
    }

    @Override
    public int getContentId() {
        return R.layout.recyclerviewtext;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ButterKnife.bind(this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onMenuItemClick(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.acitonbar_add_menu:
                reAdapter.addData(1);
                break;
            case R.id.acitonbar_delate_menu:
                reAdapter.removeData(1);
                break;
        }
        return true;
    }

    @Override
    public void onLoadMoreRequested() {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                data.add(9, new MultyItemBean(false, "我是loadMore新加的item!", 1));
                dragAndSwipAdater.notifyDataChangedAfterLoadMore(data,true);
                dragAndSwipAdater.openLoadMore(false);
            }
        }, 2111);
    }

    public void changeShowView(final int CurentDataStatu){
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                if (CurentDataStatu == mError) {
                    dragAndSwipAdater.setEmptyView(getView(R.layout.errorview));
                } else {
                    if (CurentDataStatu == mNoData) {
                        dragAndSwipAdater.setEmptyView(getView(R.layout.notdata_view));
                    } else {
                        dragAndSwipAdater.setNewData(data);
                    }
                }
            }
        }, 1100);
    }
}

总结:
可以用BaseMultiItemQuickAdapter代替BaseSectionQuickAdapter使用,也就是只用BaseMultiItemQuickAdapter和BaseItemDraggableAdapter就几乎能实现所需效果了. 有不足之处,希望大家给与指点!!!
官网地址:http://www.recyclerview.org/
同样实现以上效果,只是依赖的是另一个BaseRecyclerViewAdapterHelper包,网址: 猛戳出奇迹
最后附上借鉴demo链接:
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2016/0805/4573.html
https://github.com/xiangzhihong/BaseRecyclerViewAdapterHelper

你可能感兴趣的:(布局控件)