【FirstKotlinApp】使用Kotllin封装Adapter时ViewHolder的一点技巧
来源:互联网 发布:易通网络平台 编辑:程序博客网 时间:2024/06/05 20:55
一路做一路学,感谢互联网给我们提供的资源
学习Android开发的小伙伴们都知道,List(列表)、Grid(表格)、RecycleView等使用的是适配器模式,即需要一个Adapter为视图提供数据。而在使用Adapter的时候,getView方法内含了复用机制,即子视图的对象会循环利用,以免造成OOM。
复用机制在早期的List等中,需要开发者手动实现,其示例如下:
此处的itemView是一个上图标下文字的布局。
inner class GridItemViewHolder(val root: View) { var tvText: TextView var ivIcon: ImageView val views = SparseArray<View>()//Android推荐使用的集合框架,键值对形式存储 init {//作为主构造函数的方法体,且一定是第一个调用 tvText = getTextView(R.id.id_tv_grid_text) ivIcon = getImageView(R.id.id_iv_grid_icon) } /**使用泛型优化控件的获取**/ fun <T : View> getView(id: Int): T { var view = views[id] if (view == null) { view = root.findViewById(id) views.put(id, view) } return view as T } //提供的附加方法 fun getTextView(id: Int): TextView = getView(id) fun getImageView(id: Int): ImageView = getView(id) fun setText(id: Int, text: String) { getTextView(id).text = text } fun setIcon(id: Int, resId: Int) { getImageView(id).setImageResource(resId) } }
ViewHolder的存在是利用复用机制可循环使用对象,让其携带(通过tag属性)一个Holder对象,Holder持有子视图控件的引用,从而循环利用子视图的控件,避免重复创建对象,拉高内存占用。
但为什么需要一个外部Holder对象呢?还有没有别的方法?我想,这些肯定是有人思考过的。它的根本就在于,复用机制需要的是子视图View的对象,而这个对象本身是无法改变的,只得在其拥有的Field、方法等上下手,其tag属性终被程序员发现,这才有了ViewHolder。
这种做法显然有它的限制,那就是Java语法的限制,它规定了在语言中的一切行为,才使得无法在对象本身开刀。那么,Kotlin呢?对了,Kotlin有扩展方法,可以使我们可以忘记ViewHolder,让复用的视图自己包含缓存方法,简化代码,So Happy。
代码如下:
fun <T : View> View.findViewOften(viewId: Int): T { var viewHolder: SparseArray<View> = tag as? SparseArray<View> ?: SparseArray() tag = viewHolder var childView: View? = viewHolder.get(viewId) if (null == childView) { childView = findViewById(viewId) viewHolder.put(viewId, childView) } return childView as T}
给View扩展一个方法,内部实现与ViewHolder相同的缓存机制,这可能有人会问了,View本身如何获取?Kotlin的扩展方法需要指定接收者类型,使用this关键字即可在方法内获取,在convertView(复用的子View对象)调用该方法是,方法体便可通过this操作接收者对象,因为复用的是同一个对象,那么缓存机制便因此而实现了。
说到这里,另一个问题随之出现,Google自5.0之后推出的RecycleView自带ViewHolder的实现,且必须传入,那这个方法如何去做呢?
当然会有:
class MyViewHolder(val convertView: View) : RecyclerView.ViewHolder(convertView) { fun <T : View> findView(viewId: Int): T { return convertView.findViewOften(viewId) }}
即使必须要ViewHolder,最终也是逃离不掉convertView的,通过ViewHolder下手即可。
欢迎提出更好的实现方案。
参考来源:http://www.jianshu.com/p/819ba04955a8
额外内容:
获取被声明在arrays数组中的资源ID1.val typedArray = resources.obtainTypedArray(R.array.home_bar_icon)2.val itemInfo = ItemInfo(stringArray[i], typedArray.getResourceId(i, 0))通过对该数组获取typedArray,再获取resourceId
今天就写到这里,最近尽可能的在过好自己的生活,说到的要做到,不过放假难免有其他事,都做好互不影响并尽可能弥补自己吧
写于:2017年7月30日 20:55
- 【FirstKotlinApp】使用Kotllin封装Adapter时ViewHolder的一点技巧
- 封装的viewholder和adapter
- 【FirstKotlinApp】使用Kotlin封装6.0的权限请求流程
- 封装好的万能ViewHolder和Adapter
- RecyclerView中Adapter和ViewHolder的封装
- 封装Adapter ViewHolder
- 封装使用ViewHolder模式的Adapter组件,及用其快速实现聊天界面
- RecyclerView+RecyclerView.Adapter+RecyclerView.ViewHolder的使用
- adapter的优化---配合上一篇viewHolder的封装
- RecyclerView的ViewHolder和Adapter的封装优化
- Android之子定义Adapter使用ViewHolder和不使用时的代码比较
- Android 封装RecyclerView.Adapter,省其ViewHolder
- 使用ViewHolder模式来提高自定义adapter的效率
- Android数据适配器(Adapter)优化:使用高效的ViewHolder
- Android数据适配器(Adapter)优化:使用高效的ViewHolder
- ListView的优化使用-抽取ViewHolder以及adapter类
- Android 编程技巧之 ----- ViewHolder 的简洁封装
- ViewHolder的二次封装
- 内存中整型,浮点型的存储
- libcrypto.so.1.0.0: cannot open shared object file: No such file or directory解决方案
- effective javascript 第二章
- QQ空间经典文章分享
- Codeforces Round #413 (Div. 2)
- 【FirstKotlinApp】使用Kotllin封装Adapter时ViewHolder的一点技巧
- slice、splice和split的区别
- 毕业一年
- bzoj 4318 期望DP 解题报告
- 小明的约会 oj148
- QSlider 用法总结
- mariadb galera 集群部署
- Tomcat服务器简单介绍和配置
- linux防火墙配置