方案1
Android內(nèi)容展示類的應(yīng)用中 Recyclerview使用非常頻繁,為Recyclerview寫Adapter是一件很麻煩的事情。經(jīng)過不斷的改進送巡,誕生了一個令人滿意的簡單通用的Adapter鸭津。通用是指對應(yīng)任意的數(shù)據(jù)類型蚯舱,和任意的布局效果都可以適用英支。暫不考慮多種數(shù)據(jù)和布局混排的情況佩憾。
下面是該Adapter的kotlin代碼
open class CommonAdapter<T>(private val mLayoutId: Int, val bind: (CommonViewHolder, Int, T) -> Unit) : RecyclerView.Adapter<CommonViewHolder>() {
private var mContent: MutableList<T> = mutableListOf()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CommonViewHolder {
val view = createView(parent, viewType)
return CommonViewHolder(view)
}
override fun onBindViewHolder(holder: CommonViewHolder, position: Int) {
bind(holder, position, mContent[position])
}
override fun getItemCount(): Int = mContent.size
protected fun createView(parent: ViewGroup, viewType: Int): View {
return LayoutInflater.from(parent.context).inflate(mLayoutId, parent, false)
}
fun addItems(items: List<T>?, append: Boolean) {
items?.let {
if (!append) {
mContent.clear()
}
mContent.addAll(it)
notifyDataSetChanged()
}
}
}
非常關(guān)鍵的通用viewholder
class CommonViewHolder(view: View) : RecyclerView.ViewHolder(view) {
private val views: SparseArray<View> = SparseArray()
operator fun <T : View> get(id: Int): T {
var t = views.get(id)
if (t == null) {
t = itemView.findViewById(id)
views.put(id, t)
}
return t as T
}
}
使用Adapter的demo
fun provideHomeAdapter():CommonAdapter<Girl>{
return CommonAdapter(R.layout.viewholder_girl, { h, _, d ->
h.get<TextView>(R.id.des_view).text=d.desc
Glide.with(activity).load(d.url).fitCenter().into(h.get(R.id.image_view))
})
}
簡單解釋一下,主要是把變化的內(nèi)容抽象出來干花,通過參數(shù)傳入妄帘。借助kotlin的閉包讓代碼更精簡,不必向java那樣為每一種操作定義接口池凄。
方案2
其實還有更簡單的方法抡驼,借助Databinding框架實現(xiàn)更加簡單的通用的Adapter。數(shù)據(jù)綁定的代碼都可以在布局文件中實現(xiàn)肿仑。
下面是使用Databinding實現(xiàn)的Adapter
class DataBindingAdapter<T>(val layoutId:Int, val mContent:List<T>) :
RecyclerView.Adapter<DataBindingViewHolder>() {
override fun onBindViewHolder(holder:DataBindingViewHolder, position: Int) {
holder.binding?.let {
it.setVariable(BR.data,mContent[position])//xml文件中變量名稱要一致
it.executePendingBindings() //立刻執(zhí)行數(shù)據(jù)綁定
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DataBindingViewHolder {
val binding=DataBindingUtil.inflate<ViewDataBinding>(LayoutInflater.from(parent.context), layoutId, parent,false)
val holder= DataBindingViewHolder(binding.root)
holder.binding=binding
return holder
}
override fun getItemCount()= mContent.size
}
viewholder
class DataBindingViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var binding:ViewDataBinding?=null
}
xml布局文件略
簡單的不像話致盟。
注意事項:要想使用DatabindingAdaper 要遵循一個約定碎税,布局文件的viewmodel名稱為data。
其實方案1和2比也不是一無是處雷蹂,有些情況下匪煌,它更加靈活。至少不需要借助其他框架
多種數(shù)據(jù)和布局混排的情況
這種情況也非常的常見驳规。簡單的如給Recyclerview加header和footer。這種情況的Adaper實現(xiàn)我見過一個非常好的方法巩搏」岬祝可以最大程度的復(fù)用代碼禽捆。感興趣的可以參考以下文檔。
草梯子壞了浊服,找不到了,以后再補吧