打造一个通用的 RecyclerView Adapter(二)

radapter

使用 radapter,你可以方便的构造多种类型的列表视图。

前言

三个月没有更新博客了,主要是因为最近换了工作,在新公司还在摸爬滚打,没有时间更新,心想2018年就要结束了,不能留下遗憾,于是趁着元旦假期来一发,biu~ 以后应该会正常更新,感谢关注的朋友们。

2018年对大部分人来说是萧条的一年,我在此祝愿大家2019年红红火火,升职加薪!

不知道还有没有人记得前一篇 打造一个通用的 RecyclerView Adapter,这个版本算是比较初级的,因此也没有上传到仓库,经过自己一年来的使用,不断完善,终于推出 2.0 版本了,并且也上传了 JitPack 仓库,下面我就来介绍一下这个 2.0 版本有什么不同吧。

使用

Gradle

Step 1. Add the JitPack repository to your build file

Add it in your root build.gradle at the end of repositories:

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

Step 2. Add the dependency

dependencies {
    implementation 'com.github.wangchenyan:radapter:2.0'
}

混淆

该库已经默认添加了混淆配置,使用 AAR 依赖是不需要特殊处理的,如果使用 Jar 依赖,需要手动添加以下配置

-keepclassmembers class * extends me.wcy.radapter.RViewHolder {
    public <init>(android.view.View);
}

介绍

原始的使用 Recycler View 的方式我就不赘述了,总之是比较繁琐的,我直接介绍 radapter 如何使用。

对于多种类型的列表,我们一般是根据 getItemViewType() 区分类型,来构造、渲染视图,这种繁琐的方式大家应该已经写得要吐了吧,反正我是不想再写了。

radapter 就是来解救你的,它可以让你丢弃 Adapter,丢弃多类型时繁琐的逻辑,只需要保留有用的部分,即 ViewHolder,使 ViewHolder 可以专注于处理自己的业务。

来看一个栗子,一个图文混合的列表

// 首先,添加数据,Image 保存了图片资源ID,Text 保存了文本
val dataList = mutableListOf<Any>()
dataList.add(Image(R.mipmap.image1))
dataList.add(Text("渊虹"))
dataList.add(Image(R.mipmap.image2))
dataList.add(Text("鲨齿"))
dataList.add(Image(R.mipmap.image3))
dataList.add(Text("干将莫邪"))
dataList.add(Image(R.mipmap.image4))
dataList.add(Text("墨眉"))

// 使用 radapter,注册数据和 ViewHolder
val adapter = RAdapter(dataList)
adapter.register(Image::class.java, ImageViewHolder::class.java)
adapter.register(Text::class.java, TextViewHolder::class.java)

// 设置 adapter
recycler.layoutManager = LinearLayoutManager(this)
recycler.adapter = adapter

使用就这么简单,你只需要实现 ViewHolder 即可,看下 ViewHolder 的实现

@RLayout(R.layout.view_holder_image)
class ImageViewHolder(itemView: View) : RViewHolder<Image>(itemView) {
    override fun refresh() {
        itemView.image.setImageResource(data().resId)
    }
}

继承 RViewHolder,复写 refresh 方法刷新视图即可,可以使用父类的方法和变量

方法/变量 返回值/类型 备注
context Context 上下文
adapter() RAdapter 适配器
data() T 泛型数据
position() int 当前位置,调用 adapter 的 notifyItemInsertednotifyItemRemoved 后会自动更新位置
getExtra(key: Int) Any 可以取得 adapter.putExtra() 存放的数据,下文会介绍

这些方法/变量应该足够我们使用了。

看下效果

image

到现在,我们可以根据数据类型区分不同的 ViewHolder,但有时候同一种类型的数据,可能根据不同的属性,也要展示不同的 ViewHolder,怎么办呢?

我们把栗子稍微改一下,还是图文混合,现在可以设置文本的样式,样式不同要使用不同的 ViewHolder,看一下如何实现

// 我们给 Text 加上 style 属性
val dataList = mutableListOf<Any>()
dataList.add(Image(R.mipmap.image1))
dataList.add(Text("渊虹", 2))
dataList.add(Image(R.mipmap.image2))
dataList.add(Text("鲨齿", 1))
dataList.add(Image(R.mipmap.image3))
dataList.add(Text("干将莫邪", 2))
dataList.add(Image(R.mipmap.image4))
dataList.add(Text("墨眉", 1))

val adapter = RAdapter(dataList)
adapter.register(Image::class.java, ImageViewHolder::class.java)
// 注册 Text 时使用 RConverter,根据 Text 的属性,使用不同的 ViewHolder
adapter.register(Text::class.java, object : RConverter<Text>() {
    override fun convert(data: Text): RViewHolderWrap<Text> {
        return when (data.style) {
            1 -> RViewHolderWrap(TextViewHolder1::class.java)
            2 -> RViewHolderWrap(TextViewHolder2::class.java)
            else -> RViewHolderWrap(TextViewHolder2::class.java)
        }
    }
})

recycler.layoutManager = LinearLayoutManager(this)
recycler.adapter = adapter

仍然很简单,看下效果

image

看了 ViewHolder 的代码,我们知道,ViewHolder 和 layout 通过注解的方式绑定,但是有些同学说我想在 library 里面使用怎么办,我们知道,library 里面注解不能直接引用 R 文件里面的常量,这个也很简单,注册时使用重载方法即可

adapter.register(Image::class.java, ImageViewHolder::class.java, R.layout.view_holder_image)
adapter.register(Text::class.java, object : RConverter<Text>() {
    override fun convert(data: Text): RViewHolderWrap<Text> {
        return when (data.style) {
            1 -> RViewHolderWrap(TextViewHolder2::class.java)
            2 -> RViewHolderWrap(TextViewHolder1::class.java, R.layout.view_holder_text_1)
            else -> RViewHolderWrap(TextViewHolder1::class.java, R.layout.view_holder_text_1)
        }
    }
})

有时,我们想在 ViewHolder 里面使用 Activity/Fragment 里面的数据,这是比较麻烦的,这里我们也考虑到了

// Activity
adapter.putExtra(100, "any extra")

// ViewHolder
可以取得 adapter.putExtra() 存放的数据
val extra = adapter().getExtra(100)

是不是方便了许多。

代码

radapter

总结

大家在使用中有什么问题或建议,欢迎提 Issues

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,014评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,796评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,484评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,830评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,946评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,114评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,182评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,927评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,369评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,678评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,832评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,533评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,166评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,885评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,128评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,659评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,738评论 2 351

推荐阅读更多精彩内容