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

radapter

使用 radapter,你能够方便的构造多种类型的列表视图。java

前言

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

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

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

使用

Gradle

Step 1. Add the JitPack repository to your build filebash

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

allprojects {
	repositories {
		...
		maven { url 'https://jitpack.io' }
	}
}
复制代码

Step 2. Add the dependencyide

dependencies {
    implementation 'com.github.wangchenyan:radapter:2.0'
}
复制代码

混淆

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

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

介绍

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

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

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

迁移自个人简书 2018.12.30

相关文章
相关标签/搜索