重学RecyclerView Adapter封装的深度思考和实现

本文探讨了Adapter的封装,分析了多个开源项目的共同特点,强调了DataBinding、Kotlin支持和多ItemViewType扩展的重要性。作者提出创建全而好的Adapter框架的关键点,包括分包、DSL扩展、DataBinding支持等,并分享了如何实现ItemViewType自动适配、通用ViewModel以及扩展Anko Layout的方法。此外,作者讨论了设计框架时遵循的原则,如扩展性、可靠性、单一职责。最后,作者提到封装PagingListAdapter带来的启示,提倡使用ConcatAdapter实现头尾布局的优雅封装,并分享了项目的源码链接和未来计划。
摘要由CSDN通过智能技术生成

背景

一转眼,从一开始发布文章说带大家
封装Adapter
直到现在,过去半个月了吧,前后又仔细阅读了很多Adapter的框架源码,对Adapter的千变万化算是有了深刻的认识,真的是温故而知新,借着这次机会,我也将学到的这些优点一一的列出来告诉你,跟我一起重新认识Adapter

值得一看的Adapter开源项目

这些开源项目都有哪些相同点?

  • 这几个项目最大的共同点是都对DataBinding做了扩展,看来DataBinding大家都很认可
  • 有6个项目都用到了Kotlin,最高达到了96%,看来我们android小伙伴都爱学习,kotlin的普及率好高
  • 还有一个点都对MultiItemType做了良好的扩展,说明这确实是一个Adapter库的标配
  • 有三个项目对Paging库做了扩展,相信大家用它的机会越来越多
  • 头尾布局几乎成了框架的标配
  • Kotlin DSL或多或少的支持,写法上简洁而优美
  • 大多数都做了比较好的分库处理,按需依赖,不拖泥带水

我们如何做一个可以称之为全而好的Adapter框架呢?

我抽取几个关键词来告诉你

  • 适当分包按需依赖,提供良好的扩展性
  • kotlin支持 利用最近一个老铁的话:工欲善其事必先利其器,kotlin绝壁是一个好利器
  • DSL扩展 简洁的写法,利于阅读
  • DataBinding支持 不用质疑,有就对了
  • Paging扩展 在我看来Paging用了很多新的设计,值得我们去学习
  • 头尾布局、空布局、上拉加载,拖动,动画 提供专门的包来扩展
  • DiffUtil扩展 好的工具不要忘记使用,总会有合适的应用场景
  • anko扩展 用了kotlin怎么能不用一下anko layout,300%的布局加载效率提高不香吗?

设计这么一个框架我的坚持是什么?

你有没有陷入过一个误区?自己封装了一个东西,特别的全,什么都支持,一股脑的往里面塞东西,这个人说我想这样,你就改成这样,那个人想那样,你又开始改?难道我们做个东西就是为了让别人指挥吗?答案肯定是:不。那应该从哪几个方面考虑呢?

  • 扩展性 对的,你一定要做到可扩展,要不然你就要面临东改改,西改改的困境,如何做到可扩展呢?一条原则搞定:依赖倒转原则,尽量依赖于抽象,而不是依赖于实现,做到这一点其实还不够
  • 可靠性 可以理解为,你做的东西不要经常变,特别是抽象的接口,在一开始我们就要做到完整,有的人说,我怎么肯能考虑那么完美呢?那就要考虑一下,你是不是走到了一个误区,接口的抽象在这样一个成熟的框架中,应该很好确定的,接口不要大而全,接口也要做到尽量的小,起码接口可以多继承啊,对吧。
  • 里氏替换原则: 任何基类可以出现的地方,子类一定可以出现,这个原则其实好多人都不太理解,其实说白一点,用现实的例子告诉你,你继承了父亲的很多基因,那你能改变父亲的基因吗?肯定不能,可代码里是可以重写的(抽象方法不算哦),但这个原则就是告诉我们避免重写,一旦重写,父类就没有了意义,其实在工作中,有很多人喜欢往父类里抽象很多东西,还特别喜欢在不同的子类中覆盖后重写,这些都是不好的习惯,你不应该只是老三用到了一个东西,就要给所有的人加上这个东西,我感觉是个累赘,你觉得呢?我们在设计框架的时候,一定要遵循这些好的设计原则。
  • 单一职责 一个类应该有且仅有一个职责,你还好意思封装一个类,啥功能都有吗?除非它叫Manager,但也只能管理一类东西,职责的单一处处可见,且要处处坚持。

讲了这些废话,你是不是不耐烦了,下面来点干货吧,看看Adapter的一些细节是如何封装的

Adapter 如何做到ItemViewType自动适配?我们是如何封装的?

看源码前,我想说的是,你要明白一个原理,其实ItemViewType它影响的就是ViewHolder的复用逻辑,只要是一样的ItemViewType,它就会触发复用,所以说ItemViewType封装的目的,其实是缓存ViewHolder然后复用,那我们如何做到自动处理加缓存呢?

由于我们要做到onCreateViewHolder的下移,而我们抽象了ViewModel层来负责组织View和Model,那么ViewHolder就成了我们View的载体,抽象一个ViewHolderFactory让ViewModel继承,达到onCreateViewHolder的调用下移

typealias GenericViewHolderFactory = ViewHolderFactory<out RecyclerView.ViewHolder>

interface ViewHolderFactory<VH : RecyclerView.ViewHolder> {
    fun getViewHolder(parent: ViewGroup, layoutInflater: LayoutInflater): VH
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值