美文网首页kotlin频道
Kotlin写RecyclerView.Adapter

Kotlin写RecyclerView.Adapter

作者: 747a945a4501 | 来源:发表于2016-08-17 16:02 被阅读4248次

前言


其实RecyclerView.Adapter已经很精简了,没有多少可以缩的地方。下面也就根据自己平时使用的习惯代码上做了一些减法。

咱们平时看别人代码,维护别人的项目。其实特别讨厌代码跳来跳去。以前我一直思考为什么adapter要单独写,不用内部类呢?为了不让Activity显得那么臃肿 or adapter可以复用?
但是最近的开发思路一直在改变,觉得adapter作为Activity的一个成员 其实没有必要拆开,毕竟在adapter里面可能会用到宿主的一些资源。当然代码肯定要简单粗暴,一目了然

实现效果


定义一个Holder类,代表每一行Item的界面对象

class TextHolder : HolderBo() {
    lateinit var titleView: TextView
    lateinit var desView: TextView
    override fun rootViewInit(): AnkoContext<Context>.() -> Unit {
        return {
            linearLayout {
                layoutParams = viewGroupLP(MATCH_PARENT, WRAP_CONTENT)
                gravity = Gravity.CENTER_VERTICAL
                                titleView = textView { }.lparams(0, WRAP_CONTENT, 1f) { margin = dip(10) }
                desView = textView { }.lparams(0, WRAP_CONTENT, 1f) {                    gravity = Gravity.RIGHT
                    margin = dip(10)
                }
            }
        }
    }}

下面就是activity里面的使用的代码

recyclerView {
    layoutManager = LinearLayoutManager(context)
    adapter = KAdapter<String,TextHolder>(arrayListOf("11", "22", "11", "22", "11", "22", "11", "22", "11", "22", "11", "22")) {
        itemConstructor{ TextHolder() }
        bindData { b, s, p -> b.desView.text = "第${p}个描述$s"
                            b.titleView.text = "第${p}个标题" }
        itemClickDoing {s, i -> toastLongShow("第${i+1}个被点击")}
    }}.lparams(MATCH_PARENT, MATCH_PARENT) { below(navView) }

运行的效果如下:

Paste_Image.png

代码就那么多,实现一个列表的功能,当然这个代码还可以优化,通过给RecyclerView扩展的方式,把adapter也去掉,但是我没难做,怕优化太多,代码的可读性差

代码实现


思路其实简单,就是recycle的adapter需要哪些? 需要1.数据源,2. holder对象,3. 数据源和界面的交互,4. 点击事件。
在实际开发中,数据源一般是集合对象,很少是数组,所以我这里面用了Collection<???>
其他的只要自己封装的类 提供给他就ok了,代码如下:

首先是Holder类

class KHolder<BO : HolderBo>(val bo: BO) : RecyclerView.ViewHolder(bo.rootView) { }

abstract class HolderBo() {
    lateinit var rootView: View
    init {
        rootView = kApplication.UI {
            rootViewInit().invoke(this)
        }.view
    } 

   abstract fun rootViewInit(): AnkoContext<Context>.() -> Unit
}

然后是adapter的实现类

class KAdapter<SOURCE_BO, HOLDER : HolderBo>(var sourceData: Collection<SOURCE_BO>, doing: KAdapter<SOURCE_BO,HOLDER>.() -> Unit): RecyclerView.Adapter<KHolder<HOLDER>>() {
    private var bindData: (HOLDER, SOURCE_BO, Int) -> Unit = { b, s, positon  -> }
    
    private lateinit var itemConstructor: () -> HOLDER

    private var itemClickDoing: ((SOURCE_BO, Int) -> Unit)? = { s, i -> }

    init {  doing.invoke(this)  } 

    fun bindData(bindDataDoing :(HOLDER, SOURCE_BO, Int) -> Unit) {
      bindData = bindDataDoing
    }

    fun itemConstructor(itemBoConstructor : () -> HOLDER) {
      itemConstructor = itemBoConstructor
    }

    fun itemClickDoing(doing: (SOURCE_BO, Int) -> Unit) {
      itemClickDoing = doing
    }

     override fun getItemCount(): Int {
        return sourceData.size
      }    

      fun getItem(position: Int): SOURCE_BO {
        return sourceData.elementAt(position)
       }

      override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): KHolder<HOLDER> {
        val bo = itemBo()
        return KHolder<HOLDER>(bo)
    }

      override final fun onBindViewHolder(holder: KHolder<HOLDER>, position: Int) {
        val sourceBo = getItem(position)
        bindData.invoke(holder.bo, sourceBo,position)
        holder.itemView.onMyClick { 
           itemDoing?.invoke(sourceBo, position)
        }
    }
  }

这样就大功告成了!

相关文章

网友评论

本文标题:Kotlin写RecyclerView.Adapter

本文链接:https://www.haomeiwen.com/subject/lsvmsttx.html