博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
用Kotlin封装极简适配器,从此远离ViewHolder
阅读量:6393 次
发布时间:2019-06-23

本文共 3355 字,大约阅读时间需要 11 分钟。

作为一名Android开发者,用过ListView或者RecycleView后想必对ViewHolder再熟悉不过了。ViewHolder 一开始并不是 Android 原生提供的,而是在ListView中作为减少频繁调用findViewById而引入的,再到后来推出了更好的 RecycleView,直接内置了ViewHolder。不过我们总归逃脱不了在写适配器时写ViewHolder或者findViewById的命运。

而现在Kotlin的出现似乎轻而易举地解决了这个问题。你可能还记得,引入Kotlin后,Activity中可以直接用布局文件的Id来使用view,原理可以看下以前写过的一篇文章,本文就是用这个特性来封装一个极简地不需要自己创建ViewHolder的通用RecycleView适配器。

通用ViewHolder

首先Kotlin上述特性在普通View中默认是关闭,打开app的build.gradle,启用实验性功能:

android {...}androidExtensions {    experimental = true}复制代码

然后创建一个通用的ViewHolder,很简单只有一行代码:

class CommonViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), LayoutContainer {        override val containerView: View = itemView    }复制代码

极简适配器

我们直接上代码:

open class BaseRecyclerAdapter
( @LayoutRes val itemLayoutId: Int, list: Collection
? = null, bind: (BaseRecyclerAdapter
.() -> Unit)? = null) : RecyclerView.Adapter
() { init { if (bind != null) { apply(bind) } } private var dataList = mutableListOf
() private var mOnItemClickListener: ((v: View, position: Int) -> Unit)? = null private var mOnItemLongClickListener: ((v: View, position: Int) -> Boolean) = { _, _ -> false } private var onBindViewHolder: ((holder: CommonViewHolder, position: Int) -> Unit)? = null fun onBindViewHolder(onBindViewHolder: ((holder: CommonViewHolder, position: Int) -> Unit)) { this.onBindViewHolder = onBindViewHolder } /** * 填充数据,此操作会清除原来的数据 * * @param list 要填充的数据 * @return true:填充成功并调用刷新数据 */ fun setData(list: Collection
?): Boolean { var result = false dataList.clear() if (list != null) { result = dataList.addAll(list) } return result } /** * 根据位置获取一条数据 * * @param position View的位置 * @return 数据 */ fun getItem(position: Int) = dataList[position] override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CommonViewHolder { val itemView = LayoutInflater.from(parent.context).inflate(itemLayoutId, parent, false) val viewHolder = CommonViewHolder(itemView) itemView.setOnClickListener { mOnItemClickListener?.invoke(it, viewHolder.adapterPosition) } itemView.setOnLongClickListener { return@setOnLongClickListener mOnItemLongClickListener.invoke(it, viewHolder.adapterPosition) } return viewHolder } override fun getItemCount() = dataList.size override fun onBindViewHolder(holder: CommonViewHolder, position: Int) { if (onBindViewHolder != null) { onBindViewHolder!!.invoke(holder, position) } else { bindData(holder, position) } } open fun bindData(holder: CommonViewHolder, position: Int) { } class CommonViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView), LayoutContainer { override val containerView: View = itemView }}复制代码

使用

首先创建一个简单的布局item_textview.xml

复制代码

我们可以通过继承这个适配器来创建:

class StringAdapter : BaseRecyclerAdapter
(R.layout.item_textview) { override fun onBindViewHolder(holder: CommonViewHolder, position: Int) { super.onBindViewHolder(holder, position) holder.textview.text = getItem(position) }}复制代码

也可以采用类似DSL的形式直接创建:

val adapter = BaseRecyclerAdapter
(R.layout.item_textview) { onBindViewHolder { holder, position -> holder.textview.text = getItem(position) } }复制代码

转载于:https://juejin.im/post/5cf8b098e51d4556da53d074

你可能感兴趣的文章
东大OJ-5到100000000之间的回文质数
查看>>
linux C 快速排序法
查看>>
模仿与创新
查看>>
Python用subprocess的Popen来调用系统命令
查看>>
Java NIO与IO的差别和比較
查看>>
.NET源代码的内部排序实现
查看>>
解决Strict Standards: Only variables should be passed by reference
查看>>
数据分析≠Hadoop+NoSQL
查看>>
使用PowerDesigner画ER图详细教程
查看>>
【转】Servlet与web.xml的配置
查看>>
MyEclipse安装SVN插件
查看>>
记一次令人发狂的 bug Eclipse 开不开 tomcat 7.0
查看>>
iOS中的字符串扫描类NSScanner
查看>>
phalcon: 查找记录(Finding Records)可用的查询设置如下:
查看>>
Codeforces Round #373 (Div. 2) A. Vitya in the Countryside 水题
查看>>
微信JS-SDK文档
查看>>
[转] This function or variable may be unsafe
查看>>
Vue2.0环境搭建和测试demo
查看>>
[转]C语言判断文件是否存在
查看>>
(转载):ASCII,Unicode和UTF-8 编码
查看>>