设为首页 加入收藏

TOP

Kotlin入门(23)适配器的进阶表达(三)
2019-09-01 23:14:36 】 浏览:62
Tags:Kotlin 入门 适配器 进阶 表达
CachedViewById” class ItemHolder(override val containerView: View?) : RecyclerView.ViewHolder(containerView), LayoutContainer { fun bind(item: RecyclerInfo) { iv_pic.setImageResource(item.pic_id) tv_title.text = item.title } } }

当然,为了能够正常使用该功能,需要在适配器代码头部加上以下两行代码,其中第一行代码表示引用了Kotlin的扩展插件LayoutContainer,第二行代码与Activity的一样表示导入了指定布局文件里面所有控件对象:

import kotlinx.android.extensions.LayoutContainer
import kotlinx.android.synthetic.main.item_recycler_staggered.*

 

另外,因为LayoutContainer是Kotlin针对性提供给Android的扩展插件,所以需要修改模块的build.gradle,在文件末尾添加下面几行配置,表示允许引用安卓插件库:

androidExtensions {
    experimental = true
}

 

即使修改后的适配器代码用了新插件,外部仍旧同原来一样给循环视图设置适配器,调用代码并无任何变化:

    //第一种方式:使用采取了LayoutContainer的插件适配器
    val adapter = RecyclerStaggeredAdapter(this, RecyclerInfo.defaultStag)
    rv_staggered.adapter = adapter

采用了新的适配器插件,似乎已经大功告成,可是依然要书写单独的适配器代码,仔细研究发现这个RecyclerStaggeredAdapter还有三个要素是随着具体业务而变化的,包括:

1、列表项的布局文件资源编码,如R.layout.item_recycler_staggered;
2、列表项信息的数据结构名称,如RecyclerInfo;
3、对各种控件对象的设置操作,如ItemHolder类的bind方法;
除了以上三个要素,RecyclerStaggeredAdapter内部的其余代码都是允许复用的,因此,接下来的工作就是想办法把这三个要素抽象为公共类的某种变量。对于第一个的布局编码,可以考虑将其作为一个整型的输入参数;对于第二个的数据结构,可以考虑定义一个模板类,在外部调用时再指定具体的数据类;对于第三个的bind方法,若是Java编码早已束手无策,现用Kotlin编码正好将该方法作为一个函数参数传入。依照三个要素的三种处理对策,进而提炼出来了循环适配器的通用类RecyclerCommonAdapter,详细的Kotlin代码示例如下:

//循环视图通用适配器
//将具体业务中会变化的三类要素抽取出来,作为外部传进来的变量。这三类要素包括:
//布局文件对应的资源编号、列表项的数据结构、各个控件对象的初始化操作
class RecyclerCommonAdapter<T>(context: Context, private val layoutId: Int, private val items: List<T>, val init: (View, T) -> Unit): RecyclerBaseAdapter<RecyclerCommonAdapter.ItemHolder<T>>(context) {

    override fun getItemCount(): Int = items.size

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        val view: View = inflater.inflate(layoutId, parent, false)
        return ItemHolder<T>(view, init)
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        val vh: ItemHolder<T> = holder as ItemHolder<T>
        vh.bind(items.get(position))
    }

    //注意init是个函数形式的输入参数
    class ItemHolder<in T>(val view: View, val init: (View, T) -> Unit) : RecyclerView.ViewHolder(view) {
        fun bind(item: T) {
            init(view, item)
        }
    }
}

有了这个通用适配器,外部使用适配器只需像函数调用那样传入这三种变量就好了,具体调用的Kotlin代码如下所示:

    //第二种方式:使用把三类可变要素抽象出来的通用适配器
    val adapter = RecyclerCommonAdapter(this, R.layout.item_recycler_staggered, RecyclerInfo.defaultStag,
            {view, item ->
                val iv_pic = view.findViewById(R.id.iv_pic) as ImageView
                val tv_title = view.findViewById(R.id.tv_title) as TextView
                iv_pic.setImageResource(item.pic_id)
                tv_title.text = item.title
            })
    rv_staggered.adapter = adapter

 

最终出炉的适配器仅有十行代码不到,其中的关键技术——函数参数真是不鸣则已、一鸣惊人。至此本节的适配器实现过程终于落下帷幕,一路上可谓是过五关斩六将,硬生生把数十行的Java代码压缩到不到十行的Kotlin代码,经过不断迭代优化方取得如此彪炳战绩。尤其是最后的两种实现方式,分别运用了Kotlin的多项综合技术,才能集Kotlin精妙语法之大成。

首页 上一页 1 2 3 下一页 尾页 3/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇喜闻乐见-Android LaunchMode 下一篇安卓(Android)开发基础知识

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目