每一个APP,都离不开View的使用,小到一个登陆注册页面,大到复杂的网上商城,都是View使用的具体体现。

往往我们使用View,其实就是为了向用户展示一定的数据,因此,view的使用又总是离不开数据的。基本很多人的做法都会把数据以及view分开,但是其实在Android开发的view中已经有api接口可以完成一定量数据的存储了,这就是——View.setTag()以及View.getTag()

### 什么是setTag

setTag()是做什么的呢?SDK的解释为:Unlike IDs, tags are not used to identify views. Tags are essentially an extra piece of information that can be associated with a view. They are most often used as a convenience to store data related to views in the views themselves rather than by putting them in a separate structure.

Tag从本质上来讲是就是相关联的view的额外的信息。它们经常用来存储一些view的数据,这样做非常方便而不用存入另外的单独结构。

###setTag的一些使用场景

setTag的这个api其实隐藏的比较的深,甚至在笔者之前学习的基础教程中是完全没有提到过的(好吧,也有可能是我的基础教材选的不好)。我第一次接触这一个api是在自己在尝试的完成自己的课程设计项目时,在项目中使用了**ListView**展示一系列的数据,当时的数据量是比较的大,同时每一个listItem中的view也是比较的复杂,不仅有头像,有用户名,有标题,有内容,甚至是有图片等等。

复杂的view的创建是会比较消耗机器的性能的,大量复杂的view就不用说了。因此我便在寻找方法优化list的时候,接触了setTag().在接触Android开发以来,setTag()使用的最多的场景基本就是ListView,GridView,RecycleView,ViewPage,Gallery啊等等一系列类似用于展示大量重复的View的控件上。*因为这些控件的数据量一般会比较多,例如在夜夜项目中照片瀑布流中,一页就是30张照片,加载十几页就是几百张的图片,如果不对资源加以回收的话,即使是刘威的一加3有6G内存也都不够用~*

因此,这一些控件基本都会对视图判断是否在可视的范围,从而决定回不回收资源。**那么,问题就来了,当被回收的view再一次出现在世人的眼前的时候,机器是不是需要重新绑定数据,重新加载资源,重新绘制view?**问题的答案是肯定的,**当然要!**(都已经被回收了)那么明明已经使用过的view再来一次也要重新开始绘制,那样不是一直在重复同样的动作?**特别是在一些列表或是网格的视图中,明明每一个item都是长得一样的,也是要重复创建?**同样的事,重复的做,那就是在无谓的消耗机器性能了。**因此,我们要做的是让同样的事,只做一次就好!**

通过观察,我们可以发现,其实无论是ListView,GridView,RecycleView,ViewPage,还是Gallery,它们的使用都是离不开adapter,每一个子item的创建也是在adapter中的getView()中完成的,因此,我们**要开刀的就是adapter的getView()**.

在夜夜项目中的经理列表,如下:

![](/content/images/2016/07/726155124686308457.jpg)

每一个itemView的布局都是一样的,都包括了经理头像,名字,常去酒吧,性别,热度,驻场,以及三张小的现场图片。那么,该经理listView的adapter中getView()最正常的写法如下:

![](/content/images/2016/07/----_20160722011238.png)

其实,在itemView相同的情况下,每一次创建itemView的时候都要重复的去绑定控件,须知,项目中R文件中的id可是非常very多的,这样重复的findViewById是很消耗性能的,特别在控件还很多,一个list中的itemView也很多的情况下。那么,我们就要对绑定控件这一部分进行优化。

首先我们通过查询setTag()的源码就可以知道

![](/content/images/2016/07/----_20160722011826.png)

setTag()是把Object对象作为参数对view进行存储的。也就是说,我们要把一个itemView中的控件抽取成一个Object,在此,我们创建了一个ViewHolder

![](/content/images/2016/07/----_20160722012050.png)

然后修改getView()

![](/content/images/2016/07/----_20160722012234.png)

在第一次创建itemView的时候,完成对控件的绑定,同时吧控件作为一个object--holder,把它通过setTag()存到itemView中,再第二次使用的时候就可以通过getTag()把holder取出来直接使用,也就是说,在list中itemView相同的情况下,我们只进行了一次的控件资源绑定。是不是就省了很多?

**这样的方式是适合用所有类似的控件的。包括上文提及的GridView,RecycleView,ViewPage,Gallery等,具体可以自己发挥**

### 那么,问题又来了!

在夜夜项目中开发在线聊天IM的时候,**聊天界面的消息也是由listView实现的,但是,ItemView长得不一样啊???itemView有文本消息的,有图片消息的,也有分享的名片、酒水套餐等,一个ViewHolder根本hold不住了喂!有可能上一次创建的文本消息itemView,这一次却是要图片消息的itemView了!**

其实,这个问题根本**不用担心!!!**我们翻一翻源码又发现,还有这个东西:setTag(key,object)

![](/content/images/2016/07/----_20160722013426.png)

也就说,其实一个view中是可以setTag多个object的,我们只需要在setTag的时候指定key,只有再通过getTag(key)就可以取出相对应的object了,界面再多类型的itemView,再多不同的holder也不怕了呢~

那么我为什么又要拿出来单独说呢?因为**这里面有坑!**

假如你这样子使用:> `converView.setTag("text",textHolder);`

`converView.setTag("pic",picHolder);`

`converView.setTag(100,shareHolder);`

>

那么,恭喜你,你的项目要开始Crash了,开始抛出IllegalArgumentException的问题了~因为在SDK中有这样子说过:>*“ The specified key should be an id declared in the resources of the application to ensure it is unique (see the ID resource type). Keys identified as belonging to the Android framework or not associated with any package will cause an IllegalArgumentExceptionto be thrown.”*

**也就是说你的key必须是唯一的!!!**

那么我们要怎么实现唯一的key呢?其实我们可以把key定义在资源文件中,再由编译器生成对应的,唯一的id!因此我们可以这样写在项目的资源res/values/string.xml中:

![](/content/images/2016/07/----_20160722014903.png)

然后直接:`converView.setTag(R.id.tag_text,textHolder);`

就可以了,取值的时候:`textHolder = converView.getTag(R.id.tag_text);`

然后,你就可以愉快的撸代码啦~

###### 至此,全文基本完!

*edit by: 陈育生*

如果这篇文章又帮到你的话,请点一下‘喜欢’,我会更努力的创作的

android listview settag,Android View中setTag的二三事相关推荐

  1. android listview高级,Android中Listview点赞功能的实现

    最近这段时间一直在看Android,利用Listview去实现点赞功能,下面给大家介绍下基本思路. 基本思路: 进入界面–>获取数据–> 在Listview中显示–> 通过map集合 ...

  2. android listview qq,Android中使用listview实现qq/微信好友列表

    首先附上运行结果: 如果你没有学过listview请你先看一看基本知识.不想再说的那么细了 太多了. 首先是listview布局 android:id="@+id/lv_view" ...

  3. android listview 分析,Android中ListView用法实例分析

    本文实例分析了Android中ListView用法.分享给大家供大家参考,具体如下: 通过在Layout中添加ListView Widget可以达到在页面布局具有列表效果的交互页面.在这里通过举例来说 ...

  4. Android弹性滑动在自定义View中的高级应用

    本文出自门心叼龙的博客,属于原创类容,转载请注明出处. 好久没有更新博客了,特意的看了博客最后的更新时间为2019年7月21日,今天是10月24日掐指一算已经有三个月时间了,自从上篇<开发杂谈: ...

  5. android listview asynctask,Android精通之AsyncTask与ListView讲解

    版权声明:未经博主允许不得转载 标题图 AsyncTask 了解AsyncTask异步,需要了解一下异步任务(多线程),什么是线程,可以这么说线程好比边吃饭边看电视,AsyncTask是为了方便后台线 ...

  6. android listview ontouchlistener,Android ListView监听滑动事件的方法(详解)

    ListView的主要有两种滑动事件监听方法,OnTouchListener和OnScrollListener 1.OnTouchListener OnTouchListener方法来自View中的监 ...

  7. android listview高级,Android 高级控件笔记-列表视图ListView 基本适配器BaseAdapter

    我最近做项目用到了基本适配器BaseAdapter,所以写篇博客总结一下,希望也能对你有所帮助 什么时候用BaseAdapter(同一项存在多个控件,复杂的列表时) Android中Adapter类其 ...

  8. android listview网络图片,Android ListView从网络获取图片及文字显示

    上一篇文章说的是ListView展示本地的图片以及文本,这一篇说一下如何从网络获取图片以及文本来显示.事实上,一般是先获取Josn或sml数据,然后解释显示.我们先从网上获取xml,然后对其进行解析, ...

  9. android listview 美化,Android界面美化 -- 自定义ListView分割线

    ListView默认的分割线 ListView会在item之间添加一个默认的分割线.在XML中添加一个ListView,其对应的属性如下. 可以看到ListView默认样式中设置了一个Divider, ...

最新文章

  1. 虚拟机(基于栈还是基于寄存器)之谈
  2. 用于数据分析的Python – Pandas
  3. ajax概述原理,ajax基本原理
  4. vue2.0中vue-router使用总结
  5. in-list iterator
  6. 新能源车为什么不加变速箱解决高速高耗电的问题?
  7. 斗鱼回应与虎牙合并;Android 11 Beta 3 发布| 极客头条
  8. Ubuntu12.04 apt-get 安装mysql
  9. mysql命令桌面壁纸_【upupoo动态桌面壁纸和mysql-jdbc.jar哪个好用】upupoo动态桌面壁纸和mysql-jdbc.jar对比-ZOL下载...
  10. 计算机输入设备和输出设备怎么区分,输入设备和输出设备的区别
  11. 金蝶标准版迷你版常见问题汇总
  12. 公众号里面套页面_怎么套用别人的公众号模板,如何套用微信图文模板
  13. 智慧旅游综合运营服务平台建设方案
  14. ssh 报 You don't exist, go away
  15. Linux Centos8踩坑
  16. Ceph 中Pool、PG、OSD的关系
  17. 5G时代的来临,我们应该做好哪些网络安全准备?
  18. 300大作战怎么在电脑上玩 300大作战电脑版玩法教程
  19. QQ小游戏 BannerAd 创建banner广告组件 API
  20. 青岛abb焊接机器人编程招聘_ABB机器人焊接编程程序详细介绍

热门文章

  1. 史上卖得最多的芯片......原来是这个!
  2. 字符串类型的数字比较大小_Python核心知识系列:数字与字符串类型
  3. android 反射调用方法可不可以重载,使用Java进行反射投射和重载方法调度
  4. php如何防sql注入攻击,php防sql注入攻击(含php6)
  5. 服务器显示AL018是什么意思,IIS服务器80端口却已被占用的问题
  6. 并不对劲的bzoj5475:loj2983:p5206:[wc2019]数树
  7. 第 4 章  超链接和路径
  8. 硬件——STM32 , 录音
  9. MapReduce实例(数据去重)
  10. [转]locate命令的使用