BaseRecyclerViewAdapterHelper使用

原文:https://www.jianshu.com/p/9cf594d76975

对于RecyclerView, 我们重复编写着那一个又一个的列表界面,有的要分组,有的要添加广告头部、有的要不同类型item排列、等等需求,主要代码有大部分是重复的,如果有一个框架能够帮快速的解决各种需求,那该多好。

BRVAH是GitHub上一个强大的RecyclerAdapter框架,它能节约开发者大量的开发时间,它集成了大部分列表常用需求解决方案。 该框架于2016年4月10号发布,至今,经历了700多次迭代。

presentation by吴思博

github:https://github.com/CymChad/BaseRecyclerViewAdapterHelper

official website:www.recyclerview.org

Author(Brvah) blog:http://www.jianshu.com/u/f958e66439f0

它能干

解放你的双手,让你少码代码!

列表、子布局

一行代码轻松切换5种动画

让你感觉又回到ListView时代!

哼、列表需求来呀!

来了什么好

 

提高效率

BRVAH是Github上的一个很棒的开源项目,主要作用是帮助我们更加高效的使用Recyclerview控件,处理项目中常见需求的Adapter,使用起来非常方便。

BRVAH主要是针对Adapter来设计的,为我们提供了一般情况下的BaseQuickAdapter,和几个特定需求下的Adapter,BaseMultiItemQuickAdapter用于复杂类布局列表;BaseItemDraggableAdapter用于拖拽移动和滑动删除类列表;BaseSectionQuickAdapter用于带Section头部View的列表。

一、框架引入:

二、基本使用

Activity代码:(和普通的一样)

正常的adapter写法:

onCreateViewHolder(这个方法主要生成为每个Item inflater出一个View,方法返回的是一个ViewHolder。 方法是把View直接封装在ViewHolder中,然后我们面向的是ViewHolder这个实例,这个ViewHolder需要我们自己去编写。直接省去了当初Listview的convertView.setTag(holder)和convertView.getTag()这些繁琐的步骤。)和onBindViewHolder(这个方法主要用于适配渲染数据到View中。方法提供给你了一个viewHolder,而不是原来的convertView)等方法。

使用BRAVH的Adapter:

首先需要继承BaseQuickAdapter,然后BaseQuickAdapter中第一个泛型T是数据实体类型,第二个BaseViewHolder是ViewHolder,其目的是为了支持扩展ViewHolder。

可以通过viewHolder.getView(viewId)获取该控件。 通过viewHolder.getLayoutPosition()获取当前item的position。(为什么有数据不显示?检查一下的RecyclerView是否设置了LayoutManager。)

代码量是3:1的比例!

和原始的adapter相对,减少了70%的代码量。

实现思路:

找到重复部分代码,抽取到基类,非重复部分用抽象方法代替,具体让子类实现。具体代码BaseQuickAdapter如下:(onCreateViewHolder方法和普通adapter一样,对onBindViewHolder方法进行了提取,使用抽象方法convert(抽象方法)代替。)

接下来再看看BaseViewHolder怎么写的:( 把ViewHolder进行了封装,利用了SparseArray,加快了查找已创建好控件的速度,没有创建再使用findviewbyId再存入SparseArray)

三、强大的功能

1.复杂布局实现(多布局)

在实际应用中经常会遇到各种样式的列表、宫格和列表同时存在、分类列表等情况。

1.1多布局

在云阅读中的使用:“评论页面”(优点: 代码量少,节省时间,简洁,清晰,易维护)

普通多布局写法:

getItemViewType方法,根据位置获取当前item的类型,在onCreateViewHolder和onBindViewHolder中匹配类型进行操作。

BRAVH是怎么实现?

1、实体类(UserComment)实现MultiItemEntity接口,在设置数据的时候,给每一个数据设置itemType。

评论的实体类:

2、adapter继承BaseMultiItemQuickAdapter类,在构造方法中调用addItemType()方法加入定义的itemType和对应布局, 在Activity中实例化即可。

和原始的adapter相对,减少70%的代码量,更加清晰易于维护。

原理分析:

1.2宫格和列表的混排样式

关于Grid和List的混排样式,Grid样式是一行有多个,而List样式是一行只有一个。 我们可以把List样式看成是Grid样式,它就相当于把一个Grid的item拉长了的样子。

列表与网格混排的布局效果,我们可以创建adapter继承BaseMultiItemQuickAdapter添加对应item类型的布局文件,也可以在Activity中创建GridLayoutManager对象,设置spanSize属性,通过Adapter的setSpanSizeLookup()方法设置每种item类型对应的spanSize。设置Recyclerview的addItemDecoration()方法设置添加分割线或设置item间距。

在创建GridLayoutManager对象时,spanSize的参数需要设置,它的作用就是使原来一个item占满一行变为可以最多三个item占满一行。

而设置setSpanSizeLookup()方法返回的是对应每种item类型返回具体的横跨大小。比如代码中TYPE_GRID类型的item在设置的spanSize是1,而GridLayoutManager设置的spanSize是3,那么该类型的item就会以3个item占满一行,相当于每个item占一行的1/3。

代码片段:

在我们使用addItemDecoration()添加分割线的方法中对这种混排的列表设置item间距的时候,在getItemOffsets()方法里,通过GridLayoutManager.LayoutParams获取spanSize来确定item类型设置对应间距, 其中spanIndex表示当前行item对应的下标位置,从左到右依次从0开始。

1.3 Recyclerview嵌套Recyclerview的复杂布局

我们“文学漫画”产品中,那些地方用到这种布局?例如蜗牛的领读ReadTrendFragment、Lofter发现音乐Fragment、 云阅读书店BookStoreFragment。

蜗牛的领读ReadTrendFragmentLofter发现的音乐Fragment

这种界面布局样式,最外面一个RecyclerView,它里面嵌套一个RecyclerView。继承BaseMultiItemQuickAdapter在重写的convert()方法中实例化子Recyclerview。

需要注意的是Recyclerview嵌套Recyclerview会出现子Recyclerview抢焦点的问题, 导致界面顶部部分控件被挤出, 只需在最外面的Recyclerview的包裹容器中设置属性

Android:descendantFocusability="blocksDescendants"即可。

2.实现了点击监听事件

BRVAH为我们提供好了全面的item和item子View的监听事件,我们只需在继承它提供的Adapter的基础上,通过adapter来调用对应的监听。 设置监听子View前,我们需要在adapter中对应的item的子View注册对应的监听事件。

2.1对于item的监听事件处理

直接在Activity中添加item点击事件,和listview一样。

item长按监听事件

2.2对item中子View的监听事件处理

首先需要在adapter中,注册子View的监听事件。

2.3也可以通过viewHolder.getView(viewId)获取该控件,再设置监听。

3实现列表加载动画效果

3.1默认动画

我们只需将自建的adapter继承它对应满足需求的Adapter,然后在Activity中实例化,通过openLoadAnimation()方法完成特定的动画效果。

BRVAH支持5种动画:

渐显、缩放、从下到上,从左到右、从右到左

3.2自定义动画

我们也可以自定义动画,通过实现BaseAnimation这个类,重写

getAnimators(View view)方法来完成自定义动画。

3.3动画其他设置

动画默认只执行一次,如果想重复执行可设置: mQuickAdapter.isFirstOnly(false);

设置不显示动画数量:adapter.setNotDoAnimationCount(count);

由于进入界面的item都是很多的速度进来的所以不会出现滑动显示的依次执行动画效果,这个时候会一起执行动画,如果觉得这样的效果不好可以使用setNotDoAnimationCount设置第一屏item不执行动画, 但是如果需要依次执行动画可以重写startAnim让第一个屏幕的item动画延迟执行即可。

如何做到的?

首先判断是否开启动画,然后判断是否是自定义动画还是用户选择的自带动画,然后对动画的操作元素进行遍历执行,执行时间为300毫秒,由于上面说了每次填充数据都会调用,所以如何不判断的话,就会导致上下滑动每次都会重复调用动画,动画本身是会耗费性能的。添加一个mLastPosition来存储滑动过的位置,然后判断滑动的位置是否被滑动过,这样就可以避免每次都添加动画了。不过为了满足喜欢动画多过于性能的开发者,如果你想要每次滑动都带动画可以设置isFirstOnly属性即可,默认是不开启的。

4添加头部、尾部只需要一行代码。

添加:

删除指定view:

删除所有:

默认出现了头部就不会显示Empty,和尾部,配置以下方法也支持同时显示:

默认头部尾部都是占满一行,如果需要不占满可以配置:

其中HeaderView和FooterView可以包含多个View,LoadingMoreView在BRVAH中固定成了一个。无论HeaderView里面包含了多少个Header,HeaderView会被整体当成一个Item,所以当Adapter需要刷新HeaderView的时候始终都是刷新position = 0的位置(同理,FooterView也是一个道理)

这里需要重点理解的是HeaderView中Header的数量和RecycleView整个Item数量之间的关系,BRVAH中,HeaderView和FooterView都是LinerLayout,向这个LinerLayout中增加View是不影响RecycleView的ItemCount的。千万不要想当然的认为Add了几个Header然后ItemCount就会加几了。这点理解了源代码理解起来就很容易了

5.实现Recyclerview刷新

这个框架也帮我们实现了,下拉刷新,上拉加载等,傻瓜式实现。

5.1上拉加载

在按照BRVAH框架设置完adapter后,在Activity中让类实现BaseQuickAdapter.RequestLoadMoreListener接口,重写onLoadMoreRequested( )方法,在方法中调用mAdapter.addData()来添加新的数据,接着设置mAdapter.loadMoreComplete(),在数据都加载完后设置mAdapter.loadMoreEnd(false)显示数据加载完毕。

默认第一次加载会进入回调,如果不需要可以配置:

mQuickAdapter.disableLoadMoreIfNotFullPage();

5.2设置自定义加载布局

mQuickAdapter.setLoadMoreView(newCustomLoadMoreView());

(注意:如果上拉结束后,下拉刷新需要再次开启上拉监听,需要使用setNewData方法填充数据。)

5.3下拉刷新

6.实现分组布局

设置MySection类继承SectionEntity,创建不同的构造方法来设置item是否有header。 在adapter中,增加了convertHead()方法来加载head数据。在Activity中根据数据创建不同的MySection对象加入集合,设置给adapter。

根据数据确定不同的样式,用不同的构造方法设置item布局。

在adapter中,构造方法需要传入两个不同的布局id,第一个是item的layout id,第二个是head,item的数据加载在convert()方法中,head的数据加载在convertHead()方法中。

 

7.设置空布局

一行代码搞定。

//没有数据的时候默认显示该布局

mQuickAdapter.setEmptyView(getView());

8.实现Recyclerview拖拽滑动删除

添加RecyclerView的拖拽和滑动移除很简单,只需adapter继承BaseItemDraggableAdapter类,在Activity中,添加OnItemDragListener和OnItemSwipeListener两个接口,通过adapter配置基本属性即可。

Activity使用代码:

拖拽和滑动删除的回调方法

 

adapter需要继承BaseItemDraggableAdapter

默认不支持多个不同的ViewType之间进行拖拽,如果开发者有所需求:

9自定义ViewHolder

需要继承BaseViewHolder

publicclassMovieViewHolderextendsBaseViewHolder

然后修改adapter的第二个泛型为自定义的ViewHolder

publicclassDataBindingUseAdapterextendsBaseQuickAdapter

注意:需要单独建一个外部类继承BaseViewHolder,否则部分机型会出现ClassCastException,如果是内部类的构造方法要是public,定义的那个类也最好是public。

10添加data方法

11其它

树形列表,查看官方网站

四、总结

找到重复部分代码,抽取到基类,非重复部分用抽象方法代替,具体让子类实现。提高了代码复用率, 减少了代码量, 轻松添加各种点击事件,多布局, 一行代码添加加载动画效果,添加头部、尾部、下拉刷新、上拉加载、让你感觉又回到ListView时代! 最重要的是在我们“文学漫画”产品中也可以很好的接入。

 

Thank you!!


 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
BaseRecyclerViewAdapterHelper(以下简称BRVAH)是一个强大的 RecyclerView 适配器库。它可以方便地实现 RecyclerView 的各种功能,如多类型布局、加载更多、空布局、拖拽移动、侧滑删除等。而 QuickAdapterHelper 则是 BRVAH 的简化版,只保留了最基础的功能,使用起来更加简单。 下面是 QuickAdapterHelper使用方法: 1. 在 app 的 build.gradle 文件中添加以下依赖: ``` dependencies { implementation 'com.android.support:recyclerview-v7:28.0.0' implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.47' } ``` 2. 创建一个 Adapter 类,并继承 QuickAdapterHelper: ``` public class MyAdapter extends QuickAdapterHelper<String> { public MyAdapter(List<String> data) { super(R.layout.item_layout, data); } @Override protected void convert(QuickViewHolder holder, String item) { // 设置 item 布局中的控件值 holder.setText(R.id.tv_name, item); } } ``` 上面的代码中,R.layout.item_layout 是 item 的布局文件,data 是数据源。在 convert() 方法中,我们可以通过 QuickViewHolder 来设置 item 布局中的控件值。 3. 在 Activity 或 Fragment 中使用 Adapter: ``` RecyclerView recyclerView = findViewById(R.id.recycler_view); recyclerView.setLayoutManager(new LinearLayoutManager(this)); MyAdapter adapter = new MyAdapter(data); recyclerView.setAdapter(adapter); ``` 上面的代码中,data 是数据源,通过 MyAdapter 的构造函数传入。最后将 adapter 设置RecyclerView 中即可。 这样就完成了一个简单的 RecyclerView 列表展示。如果需要实现更多的功能,可以参考 BRVAH 的文档进行扩展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值