亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > 綜合 > 正文

Kotlin封裝RecyclerView Adapter實例教程

2024-07-21 23:03:49
字體:
來源:轉載
供稿:網友

前言

Kotlin越來越流行,在Google的推動下發展的很迅猛,現在的項目大多使用上了Kotlin,其簡練的語法糖確實能減少不少代碼。

Adapter的封裝GitHub上有很多了,但大多數封裝的太好了,是的,使用太簡單了,使用簡單、封裝力度大就導致靈活性和代碼復雜性上升,誰用誰知道,當然也有封裝簡單的。

這里我借助Kotlin的簡單語法再次操刀封裝了一下。

先看下使用

單類型的使用

val adapter=recyclerView.setUp(users, R.layout.item_layout, { holder, item ->   var binding = DataBindingUtil.getBinding<ItemLayoutBinding>(holder.itemView)   binding.nameText.text = item.name   ...  })

多類型的使用

recyclerView.setUP(users,    listItems = *arrayOf(      ListItem(R.layout.item_layout, { holder, item ->       var binding = DataBindingUtil.getBinding<ItemLayoutBinding>(holder.itemView)       binding?.nameText?.text = item.name       ...      }, {       Snackbar.make(window.decorView, it.name, Snackbar.LENGTH_SHORT).show()      }),      ListItem(R.layout.item_layout2, { holder, item ->       val nameText: TextView = holder.getView(R.id.nameText)       nameText.text = item.name       ...      }, {      })    ))

使用就是如此簡單,再來看下代碼是不是過度封裝

Adapter的基類

abstract class AbstractAdapter<ITEM> constructor(protected var itemList: List<ITEM>) : RecyclerView.Adapter<AbstractAdapter.Holder>() { override fun getItemCount() = itemList.size override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {  val view = createItemView(parent, viewType)  val viewHolder = Holder(view)  val itemView = viewHolder.itemView  itemView.setOnClickListener {   val adapterPosition = viewHolder.adapterPosition   if (adapterPosition != RecyclerView.NO_POSITION) {    onItemClick(itemView, adapterPosition)   }  }  return viewHolder } fun update(items: List<ITEM>) {  updateAdapterWithDiffResult(calculateDiff(items)) } private fun updateAdapterWithDiffResult(result: DiffUtil.DiffResult) {  result.dispatchUpdatesTo(this) } private fun calculateDiff(newItems: List<ITEM>) =   DiffUtil.calculateDiff(DiffUtilCallback(itemList, newItems)) fun add(item: ITEM) {  itemList.toMutableList().add(item)  notifyItemInserted(itemList.size) } fun remove(position: Int) {  itemList.toMutableList().removeAt(position)  notifyItemRemoved(position) } final override fun onViewRecycled(holder: Holder) {  super.onViewRecycled(holder)  onViewRecycled(holder.itemView) } protected open fun onViewRecycled(itemView: View) { } protected open fun onItemClick(itemView: View, position: Int) { } protected abstract fun createItemView(parent: ViewGroup, viewType: Int): View class Holder(itemView: View) : RecyclerView.ViewHolder(itemView) {  private val views = SparseArray<View>()  fun <T : View> getView(viewId: Int): T {   var view = views[viewId]   if (view == null) {    view = itemView.findViewById(viewId)    views.put(viewId, view)   }   return view as T  } }}

子類的實現和RecyclerView的擴展

class SingleAdapter<ITEM>(items: List<ITEM>,       private val layoutResId: Int,       private val bindHolder: (Holder, ITEM) -> Unit) : AbstractAdapter<ITEM>(items) { private var itemClick: (ITEM) -> Unit = {} constructor(items: List<ITEM>,    layoutResId: Int,    bindHolder: (Holder, ITEM) -> Unit,    itemClick: (ITEM) -> Unit = {}) : this(items, layoutResId, bindHolder) {  this.itemClick = itemClick } override fun createItemView(parent: ViewGroup, viewType: Int): View {  var view = parent inflate layoutResId  if (view.tag?.toString()?.contains("layout/") == true) {   DataBindingUtil.bind<ViewDataBinding>(view)  }  return view } override fun onBindViewHolder(holder: Holder, position: Int) {  bindHolder(holder, itemList[position]) } override fun onItemClick(itemView: View, position: Int) {  itemClick(itemList[position]) }}class MultiAdapter<ITEM : ListItemI>(private val items: List<ITEM>,          private val bindHolder: (Holder, ITEM) -> Unit) : AbstractAdapter<ITEM>(items) { private var itemClick: (ITEM) -> Unit = {} private lateinit var listItems: Array<out ListItem<ITEM>> constructor(items: List<ITEM>,    listItems: Array<out ListItem<ITEM>>,    bindHolder: (Holder, ITEM) -> Unit,    itemClick: (ITEM) -> Unit = {}) : this(items, bindHolder) {  this.itemClick = itemClick  this.listItems = listItems } override fun createItemView(parent: ViewGroup, viewType: Int): View {  var view = parent inflate getLayoutId(viewType)  if (view.tag?.toString()?.contains("layout/") == true) {   DataBindingUtil.bind<ViewDataBinding>(view)  }  return view } private fun getLayoutId(viewType: Int): Int {  var layoutId = -1  listItems.forEach {   if (it.layoutResId == viewType) {    layoutId = it.layoutResId    return@forEach   }  }  return layoutId } override fun getItemViewType(position: Int): Int {  return items[position].getType() } override fun onBindViewHolder(holder: Holder, position: Int) {  bindHolder(holder, itemList[position]) } override fun onItemClick(itemView: View, position: Int) {  itemClick(itemList[position]) }}fun <ITEM> RecyclerView.setUp(items: List<ITEM>,        layoutResId: Int,        bindHolder: (AbstractAdapter.Holder, ITEM) -> Unit,        itemClick: (ITEM) -> Unit = {},        manager: RecyclerView.LayoutManager = LinearLayoutManager(this.context)): AbstractAdapter<ITEM> { val singleAdapter by lazy {  SingleAdapter(items, layoutResId, { holder, item ->   bindHolder(holder, item)  }, {   itemClick(it)  }) } layoutManager = manager adapter = singleAdapter return singleAdapter}fun <ITEM : ListItemI> RecyclerView.setUP(items: List<ITEM>,           manager: RecyclerView.LayoutManager = LinearLayoutManager(this.context),           vararg listItems: ListItem<ITEM>): AbstractAdapter<ITEM> { val multiAdapter by lazy {  MultiAdapter(items, listItems, { holder, item ->   var listItem: ListItem<ITEM>? = getListItem(listItems, item)   listItem?.bindHolder?.invoke(holder, item)  }, { item ->   var listItem: ListItem<ITEM>? = getListItem(listItems, item)   listItem?.itemClick?.invoke(item)  }) } layoutManager = manager adapter = multiAdapter return multiAdapter}private fun <ITEM : ListItemI> getListItem(listItems: Array<out ListItem<ITEM>>, item: ITEM): ListItem<ITEM>? { var listItem: ListItem<ITEM>? = null listItems.forEach {  if (it.layoutResId == item.getType()) {   listItem = it   return@forEach  } } return listItem}class ListItem<ITEM>(val layoutResId: Int,      val bindHolder: (holder: AbstractAdapter.Holder, item: ITEM) -> Unit,      val itemClick: (item: ITEM) -> Unit = {})interface ListItemI { fun getType(): Int}

ok,所有核心代碼,沒有了,也不打算發布rar,要用的直接clone下來引入項目,這是最好的方式,因為不復雜,要改隨時可以改。

看上面的多類型的使用,可以發現它是支持普通Layout和DataBinding Layout的,這也是本庫的一個特色,不需要多余的處理。

1.普通的Layout 這樣處理

ListItem(R.layout.item_layout2, { holder, item ->       val nameText: TextView = holder.getView(R.id.nameText)       nameText.text = item.name      }

通過Holder來操作View,里面有做緩存的。

DataBinding LayoutListItem(R.layout.item_layout, { holder, item ->       var binding = DataBindingUtil.getBinding<ItemLayoutBinding>(holder.itemView)       binding.nameText.text = item.name      }

是不是只要自己知道是哪中Layout,對應處理就可以了,Holder處理方式也是可以處理DataBinding Layout的,要知曉。

這里提下,可能有人會問干嘛不直接用Kotlin的Layout View 查找方法???

那樣代碼看起來是簡單,但是現在的Studio 對這個的支持不是很好,經常報紅,程序員看到紅會煩躁?。。∪绻€是喜歡的話實現也很簡單,改成View的擴展返回就可以了,可以自己動手試下哦。

因為這里只是對不變的部分進行了封裝,沒有很多華麗麗的添加頭部、腳部啥的功能,點擊事件倒是內置了一種,當然點擊事件還可以用ItemTouchHelper實現,都是可以的。

這樣每次就不用寫一大串的Adaper了,是不是可以開心地泡壺茶,吹口氣了。

別的庫都可以Item復用的,你的可以嗎?

嗯嗯、、?可以的

比如

val item: (AbstractAdapter.Holder, User) -> Unit = { holder, user ->  }

再比如

ListItem(R.layout.item_layout, { holder, item ->       var binding = DataBindingUtil.getBinding<ItemLayoutBinding>(holder.itemView)      }, {//點擊事件       Snackbar.make(window.decorView, it.name, Snackbar.LENGTH_SHORT).show()      })

是不是一樣可以的 只要定義到一個地方 然后設置進去就可以了,復用也是難不倒它的。只能說Kotlin語法大法好。

好了,這個庫就介紹到這里了,謝謝大家。

代碼地址

參考鏈接

靈感來自下面這位大神,但是我基本重寫了

https://github.com/armcha/Kadapter

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VeVb武林網的支持。


注:相關教程知識閱讀請移步到kotlin教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲图片制服诱惑| 久久久成人av| 亚洲美女www午夜| 国产美女精品视频免费观看| 欧美黄色片在线观看| 亚洲已满18点击进入在线看片| 国产日韩视频在线观看| 麻豆国产精品va在线观看不卡| 粉嫩av一区二区三区免费野| 久久视频国产精品免费视频在线| 国产亚洲欧洲高清一区| 成人网在线观看| 国产精品av在线| 九九精品在线视频| 欧美日本精品在线| 国产日韩在线免费| 中文字幕亚洲图片| 亚洲成人a**站| 97超级碰碰碰久久久| 久久国产视频网站| 4388成人网| 97精品国产aⅴ7777| 美女久久久久久久久久久| 欧美综合在线第二页| 色综合伊人色综合网| 81精品国产乱码久久久久久| 国产精品高潮呻吟久久av黑人| 久久天天躁狠狠躁老女人| 中文字幕无线精品亚洲乱码一区| 136fldh精品导航福利| 亚洲国产精品va在线看黑人| 欧美高清视频免费观看| 国产在线不卡精品| 久久久精品免费| 日韩精品www| 欧美性猛交xxxx乱大交蜜桃| 97成人精品区在线播放| 欧美成人sm免费视频| 日韩国产高清视频在线| 亚洲欧美精品suv| 大伊人狠狠躁夜夜躁av一区| 一区二区亚洲欧洲国产日韩| 国产丝袜一区视频在线观看| 在线看福利67194| 日本久久久久亚洲中字幕| 国产精品久久一| 日韩高清免费在线| 亚洲国产成人精品女人久久久| 亚洲三级黄色在线观看| 一区二区三区四区在线观看视频| 国产男人精品视频| 日本久久久久亚洲中字幕| 日韩中文字幕免费视频| 3344国产精品免费看| 国产亚洲福利一区| 91嫩草在线视频| 成人免费视频网| 国产精品偷伦免费视频观看的| 色婷婷综合成人av| 国产精品亚洲视频在线观看| 精品亚洲国产视频| 国产精品专区h在线观看| 午夜精品久久久久久久久久久久| 91久久在线播放| 欧美成aaa人片在线观看蜜臀| 国产精品第七影院| 国产一区二区三区毛片| 久久精品一本久久99精品| 亚洲人成电影网站色www| 亚洲奶大毛多的老太婆| 亚洲精品国产精品久久清纯直播| 国产在线观看一区二区三区| 欧美激情中文字幕乱码免费| 久久精品99无色码中文字幕| 欧美激情一区二区三区久久久| 久久精品99久久久久久久久| 亚洲老板91色精品久久| 性色av一区二区三区| 亚洲iv一区二区三区| 大胆人体色综合| 亚洲日韩欧美视频一区| 亚洲va男人天堂| 久久免费精品视频| 日韩视频第一页| 中文字幕av一区中文字幕天堂| 国产激情视频一区| 国产在线视频91| 国产午夜精品麻豆| 国内精品久久久久久中文字幕| 国产99久久精品一区二区 夜夜躁日日躁| 91在线视频一区| 国产91精品久久久久久久| 国产精品吴梦梦| 91久久久在线| 91久久在线观看| 亚洲欧洲视频在线| 午夜精品久久久久久久99黑人| 国产免费成人av| 大胆欧美人体视频| 亚洲人成电影在线播放| 91成人在线观看国产| 欧美极品少妇与黑人| 日韩av免费看网站| 91亚洲国产成人久久精品网站| 精品国产一区二区三区久久狼5月| 国产自产女人91一区在线观看| 亚洲精品中文字幕女同| 国产www精品| 97人人模人人爽人人喊中文字| 97色在线视频| 日韩av一区二区在线| 欧美极品少妇全裸体| 尤物yw午夜国产精品视频明星| 日韩中文字幕精品视频| 欧美一区二区三区免费观看| 欧美在线观看网站| 日韩高清电影免费观看完整版| 九九精品视频在线观看| 亚洲v日韩v综合v精品v| 欧美激情亚洲一区| 91在线观看免费网站| 亚洲精品综合久久中文字幕| 亚洲欧美在线第一页| 色噜噜国产精品视频一区二区| 日韩电影在线观看中文字幕| 精品日本美女福利在线观看| 欧美一级大片在线观看| 欧美精品性视频| 国产网站欧美日韩免费精品在线观看| 国产一区视频在线播放| 亚洲成人av中文字幕| 欧美激情欧美激情在线五月| 2019精品视频| 久久99久久99精品中文字幕| 国产成人在线一区二区| 国产原创欧美精品| 国产精品久久久久久久av电影| 日本午夜在线亚洲.国产| 91理论片午午论夜理片久久| 一区二区三区日韩在线| 色综合老司机第九色激情| www.亚洲天堂| 国产精品网红直播| 日韩成人av一区| 色综合亚洲精品激情狠狠| 久久精品最新地址| 欧美精品videos性欧美| 日韩在线免费观看视频| 777国产偷窥盗摄精品视频| 在线视频精品一| 欧美黄色www| 久久国产加勒比精品无码| 亚洲精品福利免费在线观看| 国产成人精品网站| 久久综合免费视频影院| 久久精品视频在线观看| 日韩最新中文字幕电影免费看| 日韩精品中文字幕视频在线| 精品国内自产拍在线观看| 欧美日韩中文在线| 国产自产女人91一区在线观看| 亚洲欧洲激情在线| 亚州精品天堂中文字幕| 成人精品一区二区三区|