打造一個通用的 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

相關文章
相關標籤/搜索