Skip to content

3.BRVAH简介

版本介绍: 2.x:BRVAH官方使用指南(持续更新) 3.x:BaseQuickAdapter V3RecyclerView框架——BRVAH3.x使用指南_Mondarzy的博客-CSDN博客 3.x:BaseQuickAdapter V4 框架好用是好用不过每个版本变化很多,每个新版本都不向下兼容。目前版本V4的beta版(对外公测版)已经上线很久了不过至今似乎还没有稳定版。本文基于V3使用。然后还有一点就是BRAVH开源仓库已经3个月没有提交新修改了。(网传已经不更新)推荐使用BRV框架替代不再维护的BRVAH · Issue #3608 · CymChad/BaseRecyclerViewAdapterHelperJitPack | Publish JVM and Android librariesimage.png

BRAVH的简单使用

引入依赖

在setting.gradle下加入maven扩展库地址

groovy
maven { url 'https://jitpack.io' }

在app的build.gradle下引入依赖

groovy
implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.11'

image.pngimage.png

添加控件与子项布局文件

image.pngimage.png

创建数据实体类以及数据源

image.pngimage.png

继承BRAVH自定义数据适配器

我们不再使用原生的RecyclerView.Adapter<>()而是需要继承BaseQuickAdapter,然后 BaseQuickAdapter<T, VH : BaseViewHolder>第一个泛型 T 是数据实体类型,第二个BaseViewHolder是ViewHolder,其目的是为了支持扩展ViewHolder。

java

/**
 * 第一个泛型Status是数据实体类型,
 * 第二个BaseViewHolder是ViewHolder其目的是为了支持扩展ViewHolder。
 */
@SuppressWarnings("all")
public class BravhAdapter extends BaseQuickAdapter<Fruit, BaseViewHolder> {
    /**
     * 
     * @param layoutResId 布局id
     * @param data 数据源,可空时为空数据
     */
    public BravhAdapter(int layoutResId, @Nullable List<Fruit> data) {
        super(layoutResId, data);
    }
    
    @Override
    protected void convert(@NonNull BaseViewHolder holder, Fruit fruit) {
        holder.setText(R.id.fruit_name,fruit.getName())
                .setText(R.id.fruit_button,"购买水果")
                .setImageResource(R.id.fruit_img,R.drawable.orange);
    }
}

image.png

RecyclerView绑定Adapter

运行查看效果 image.pngimage.png

点击事件

item的单击事件

java
//BravhActvity
// 设置item点击事件
adapter.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(@NonNull BaseQuickAdapter adapter, @NonNull View view, int position) {
        Toast.makeText(BravhActivity.this,"onItemClick " + position,Toast.LENGTH_SHORT).show();
    }
});

image.png

item的长按事件

java
// 设置item长按事件
adapter.setOnItemLongClickListener(new OnItemLongClickListener() {
    @Override
    public boolean onItemLongClick(@NonNull BaseQuickAdapter<?, ?> adapter, @NonNull View view, int position) {
        Toast.makeText(BravhActivity.this,"OnItemLongClick " + position,Toast.LENGTH_SHORT).show();
        return false;
    }
});

image.png

item中子View的单击事件

java
// 先注册需要点击的子控件id(注意,请不要写在convert方法里)
adapter.addChildClickViewIds(R.id.fruit_button, R.id.fruit_img);
// 设置子控件点击监听
adapter.setOnItemChildClickListener(new OnItemChildClickListener() {
    @Override
    public void onItemChildClick(@NonNull BaseQuickAdapter adapter, @NonNull View view, int position) {
        switch (view.getId()){
            case R.id.fruit_button:{
                Toast.makeText(BravhActivity.this,"单击了购买按钮" + position,Toast.LENGTH_SHORT).show();
            }break;
            case R.id.fruit_img:{
                Toast.makeText(BravhActivity.this,"单击了水果图片" + position,Toast.LENGTH_SHORT).show();
            }break;
            default:break;
        }
    }
});

image.png

item中子View的长按事件

java
// 先注册需要长按的子控件id(注意,请不要写在convert方法里)
adapter.addChildLongClickViewIds(R.id.fruit_button, R.id.fruit_img);
// 设置子控件长按监听
adapter.setOnItemChildLongClickListener(new OnItemChildLongClickListener() {
    @Override
    public boolean onItemChildLongClick(@NonNull BaseQuickAdapter adapter, @NonNull View view, int position) {
        switch (view.getId()){
            case R.id.fruit_button:{
                Toast.makeText(BravhActivity.this,"长按了购买按钮" + position,Toast.LENGTH_SHORT).show();
            }break;
            case R.id.fruit_img:{
                Toast.makeText(BravhActivity.this,"长按了水果图片" + position,Toast.LENGTH_SHORT).show();
            }break;
            default:break;
        }
        return true;
    }
});

image.png

列表加载动画

通过setAnimationEnable(true);方法可以设置item动画的开启和关闭(默认开启) 通过一行代码即可使用动画:

java
adapter.setAnimationWithDefault(BaseQuickAdapter.AnimationType.SlideInLeft);

AlphaIn:淡入动画(默认) ScaleIn:缩放动画 SlideInBottom:从底部滑入的动画。 SlideInLeft:从左侧滑入的动画。 SlideInRight:从右侧滑入的动画。

java
/**
 * 使用内置默认动画设置
 * @param animationType AnimationType
 */
fun setAnimationWithDefault(animationType: AnimationType) {
    adapterAnimation = when (animationType) {
        AnimationType.AlphaIn -> AlphaInAnimation()
        AnimationType.ScaleIn -> ScaleInAnimation()
        AnimationType.SlideInBottom -> SlideInBottomAnimation()
        AnimationType.SlideInLeft -> SlideInLeftAnimation()
        AnimationType.SlideInRight -> SlideInRightAnimation()
    }
}

2.gif2.gif2.gif

拖拽和侧滑

拖拽开启

  1. Adapter实现DraggableModule接口
  2. 在Activity中开启拖拽和侧滑

如果想实现拖拽和侧滑,首先需要在Adapter中实现DraggableModule接口,只需实现即可无需重写任何方法。 其次在Activity中开启拖拽和侧滑的功能就可以了,可以说是相当简单。 image.png

拖拽事件监听

展开来说一说拖拽的事件监听吧。拖拽事件分为3个阶段:拖拽开始,拖拽进行中,拖拽结束。其中最为重要的就是拖拽进行中的,其方法有4个参数,其意义分别如下:

  • RecyclerView.ViewHolder source 用户选中的item
  • **int from **用户选中的item的position
  • RecyclerView.ViewHolder target 要移动到的终点位置item
  • **int to ** 要移动到的终点位置item的终点item
java
//设置拖拽
adapter.getDraggableModule().setDragEnabled(true);//允许拖拽
//拖拽的事件监听
adapter.getDraggableModule().setOnItemDragListener(new OnItemDragListener() {
    //拖拽开始
    @Override
    public void onItemDragStart(RecyclerView.ViewHolder viewHolder, int pos) {

    }
    //拖拽正在进行中

    /**
     *
     * @param source 用户选中的item
     * @param from  用户选中的item的position
     * @param target 要移动到的终点位置item
     * @param to   要移动到的终点位置item的终点item
     */
    @Override
    public void onItemDragMoving(RecyclerView.ViewHolder source, int from, RecyclerView.ViewHolder target, int to) {
        //获取用户选中的item上的fruit_name控件
        TextView sourceView=(source.itemView.findViewById(R.id.fruit_name));
        String sourceStr=sourceView.getText().toString();

        //获取要移动到的终点位置item的fruit_name控件
        TextView targetView=(target.itemView.findViewById(R.id.fruit_name));
        String targetStr=targetView.getText().toString();

        Toast.makeText(BravhActivity.this,sourceStr+",position="+from+"  "+targetStr+",position="+to ,Toast.LENGTH_SHORT).show();

    }
    //拖拽结束
    @Override
    public void onItemDragEnd(RecyclerView.ViewHolder viewHolder, int pos) {

    }
});

侧滑开启与事件监听

对于侧滑和拖拽的使用是雷同的。 侧滑的事件监听有4个回调方法,侧滑开始,侧滑结束,item被成功移除,侧滑进行中。 侧滑结束与item被成功移除的区别在于,无论item是否移除侧滑结束方法都会被回调,但是item被成功移除方法只有在item被移除了才会回调。

java
adapter.getDraggableModule().setSwipeEnabled(true);//开启侧滑
adapter.getDraggableModule().setOnItemSwipeListener(new OnItemSwipeListener() {
    //侧滑开始
    @Override
    public void onItemSwipeStart(RecyclerView.ViewHolder viewHolder, int pos) {
        Log.d(TAG, "onItemSwipeStart: 侧滑开始 此时position="+pos);
    }
    //侧滑结束时回调,移除成功pos为-1
    @Override
    public void clearView(RecyclerView.ViewHolder viewHolder, int pos) {
        Log.d(TAG, "clearView: 侧滑结束 此时position="+pos);
    }
    //item被移除时回调。pos为被移除的item的position
    @Override
    public void onItemSwiped(RecyclerView.ViewHolder viewHolder, int pos) {
        Log.d(TAG, "onItemSwiped: item被移除 此时position="+pos);
    }
    //侧滑进行中,会被多次回调
    @Override
    public void onItemSwipeMoving(Canvas canvas, RecyclerView.ViewHolder viewHolder, float dX, float dY, boolean isCurrentlyActive) {
//                Log.d(TAG, "onItemSwipeMoving: dx="+dX+"  dy="+dY+"  active="+isCurrentlyActive);
    }
});

2.gif3.gif

加载更多

上滑加载更多功能的使用也很简单

  1. adapter实现LoadMoreModule接口
  2. 在Activity中实现上滑加载更多的事件监听

首先我们在adapter中实现接口

然后在Activity中设置加载数据的事件监听。通过addData()方法设置添加的数据,通过getLoadMoreModule().loadMoreComplete();方法设置下拉刷新的状态为完成。

java
//加载更多
adapter.getLoadMoreModule().setOnLoadMoreListener(new OnLoadMoreListener() {
    @Override
    public void onLoadMore() {
        List<Fruit> moreList=new ArrayList<>();
        for(int i=1;i<10;++i){
            Fruit fruit=new Fruit("新"+i+"号橘子");
            moreList.add(fruit);
        }
        adapter.addData(moreList);
        adapter.getLoadMoreModule().loadMoreComplete();
    }
});

框架默认会自动加载数据,只要用户往下话就会不断的加载新数据。当然我们也可以通过响应用户的点击事件来加载新数据。 为了模拟网络请求数据的过程,我设置一个子线程

java
public class BravhActivity extends AppCompatActivity {

    private final static String TAG="BravhActivity";
    RecyclerView recyclerView;
    BravhAdapter adapter;
    public List<Fruit> fruitList=new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bravh);
        
        ···
        
        Handler handler=new Handler(){
            @Override
            public void handleMessage(@NonNull Message msg) {
                super.handleMessage(msg);
                if(msg.what==200){
                    List<Fruit> moreList=new ArrayList<>();
                    for(int i=1;i<10;++i){
                        Fruit fruit=new Fruit("新"+i+"号橘子");
                        moreList.add(fruit);
                    }
                    adapter.addData(moreList);
                    adapter.getLoadMoreModule().loadMoreFail();
                }
            }
        };
        //手动加载更多
        adapter.getLoadMoreModule().setAutoLoadMore(false);
        adapter.getLoadMoreModule().setOnLoadMoreListener(new OnLoadMoreListener() {
            @Override
            public void onLoadMore() {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        Message msg=new Message();
                        msg.what=200;
                        handler.sendMessage(msg);
                    }
                }).start();
            }
        });

        ···
        
    }
}