当前位置: 首页 > 编程日记 > 正文

convertViewsetTag方法的一点理解

转自:http://blog.163.com/freemanls@126/blog/static/164585061201171210504864/

前言

首先我们要知道setTag方法是干什么的,SDK解释为

Tags

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不像ID是用标示view的。Tag从本质上来讲是就是相关联的view的额外的信息。它们经常用来存储一些view的数据,这样做非常方便而不用存入另外的单独结构。

convertView中的TAG

  1. 对于使用了LayoutInflater对象进行View扩充的Tag的使用

在之前,在adapter中,我们在getView中是这么些的代码:

public View getView(int position, View convertView, ViewGroup parent) {

ViewHolder holder = null;

if (convertView == null) {

holder = new ViewHolder();

convertView = inflater.inflate(R.layout.vlist2, null);

holder.img = (ImageView) convertView.findViewById(R.id.img);

holder.title = (TextView) convertView.findViewById(R.id.title);

holder.info = (TextView)

convertView.findViewById(R.id.info);

// setTag的妙用

convertView.setTag(holder);

} else {

// setTag的妙用

holder = (ViewHolder) convertView.getTag();

}

……略

}

注意标红的地方,他们是使用了Tag的。

首先我们要知道setTag方法是干什么的,他是给View对象的一个标签,标签可以是任何内容,我们这里把他设置成了一个对象,因为我们是把vlist2.xml的元素抽象出来成为一个类ViewHolder,用了setTag,这个标签就是ViewHolder实例化后对象的一个属性。我们之后对于ViewHolder实例化的对象holder的操作,都会因为java的引用机制而一直存活并改变convertView的内容,而不是每次都是去new一个。我们就这样达到的重用——我希望我说清楚了。如果有更简单的解释,请指教。

这是我们在Adapter中的使用,那么我们在这里不使用Tag标签会怎么样呢?

我们试想,如果我们不用Tag标签,那么我们的对象如何与convertView缓存结合并达到合理的效率利用?貌似答案并不明朗——所以使用Tag是比较明智的做法。

  1. 对于没有使用LayoutInflater对象进行View扩充的Tag的使用。

if (convertView != null) {

view = convertView;

...

} else {

view = new Xxx(...);

...

}

这是我们的程序,我们看到,貌似没有用Tag——是的,当没有使用LayoutInflater进行View的扩充的时候,是没有必要用的,虽然也可以用。

  1. 对于其他View的Tag使用

我们可以对所有的View对象进行操作,至于怎么用,就看作者怎么想的了,下面举例说一个View的子类button对于tag的一个使用。

直接贴代码了:

public class ButtonTagTestActivity extends Activity implements OnClickListener {

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

Button button1 = (Button) findViewById(R.id.button1);

Button button2 = (Button) findViewById(R.id.button2);

Button button3 = (Button) findViewById(R.id.button3);

button1.setTag(1);

       button2.setTag(2);

       button3.setTag(3);

button1.setOnClickListener(this);

}

@Override

public void onClick(View arg0) {

// TODO Auto-generated method stub

int tag = (Integer) arg0.getTag();

switch (tag) {

case 1: {

Toast.makeText(this, "我是button1", Toast.LENGTH_LONG).show();

break;

}

case 2: {

Toast.makeText(this, "我是button2", Toast.LENGTH_LONG).show();

break;

}

case 3: {

Toast.makeText(this, "我是button3", Toast.LENGTH_LONG).show();

break;

}

default: {

break;

}

}

}

}

Xml页面代码就不贴了。这个例子是点击界面上的3个button然后会显示用户点击的按钮。我们的程序是实现了页面全局监听,在监听前设置了每个button的tag,之后我们在switch的时候,使用getTag取出的标签来看是什么操作。

这样做的好处是可以将监听集中管理,提高代码的易读性——当然,这是我的自我理解。

后记

看了这么多的实例,我想已经明白了Tag以及convertView。

对我们知道了Tag的作用就是设置标签,标签可以是任意玩意。

以及convertView是如何在程序中使代码运行变的效率的:利用缓存convertView尽可能少实例化同样结构体的对象;

补充:

listview加载性能优化ViewHolder

在android开发中Listview是一个很重要的组件,它以列表的形式根据数据的长自适应展示具体内容,用户可以自由的定义listview每一列的布局,但当listview有大量的数据需要加载的时候,会占据大量内存,影响性能,这时候就需要按需填充并重新使用view来减少对象的创建。

ListView加载数据都是在public View getView(int position, View convertView, ViewGroup parent) {}方法中进行的(要自定义listview都需要重写listadapter:如BaseAdapter,SimpleAdapter,CursorAdapter的等的getvView方法),优化listview的加载速度就要让convertView匹配列表类型,并最大程度上的重新使用convertView。

getview的加载方法一般有以下三种种方式:

最慢的加载方式是每一次都重新定义一个View载入布局,再加载数据

public View getView(int position, View convertView, ViewGroup parent) {

View item = mInflater.inflate(R.layout.list_item_icon_text, null);

((TextView) item.findViewById(R.id.text)).setText(DATA[position]);

((ImageView) item.findViewById(R.id.icon)).setImageBitmap(

(position & 1) == 1 ? mIcon1 : mIcon2);

return item;

}

正确的加载方式是当convertView不为空的时候直接重新使用convertView从而减少了很多不必要的View的创建,然后加载数据

public View getView(int position, View convertView, ViewGroup parent) {

if (convertView == null) {

convertView = mInflater.inflate(R.layout.item, parent, false);

}

((TextView) convertView.findViewById(R.id.text)).setText(DATA[position]);

((ImageView) convertView.findViewById(R.id.icon)).setImageBitmap(

(position & 1) == 1 ? mIcon1 : mIcon2);

return convertView;

}

最快的方式是定义一个ViewHolder,将convetView的tag设置为ViewHolder,不为空时重新使用即可

static class ViewHolder {

TextView text;

ImageView icon;

}

public View getView(int position, View convertView, ViewGroup parent) {

ViewHolder holder;

if (convertView == null) {

convertView = mInflater.inflate(R.layout.list_item_icon_text,

parent, false);

holder = new ViewHolder();

holder.text = (TextView) convertView.findViewById(R.id.text);

holder.icon = (ImageView) convertView.findViewById(R.id.icon);

convertView.setTag(holder);

} else {

holder = (ViewHolder) convertView.getTag();

}

holder.text.setText(DATA[position]);

holder.icon.setImageBitmap((position & 1) == 1 ? mIcon1 : mIcon2);

return convertView;

}

三种方式加载效率对比如下图所示:

说明:上述三个例子代码摘自google 2010 I/O大会

当处理一些耗时的资源加载的时候需要做到以下几点,以使你的加载更快更平滑:

1.   适配器在界面主线程中进行修改

2.   可以在任何地方获取数据但应该在另外一个地方请求数据

3.   在主界面的线程中提交适配器的变化并调用notifyDataSetChanged()方法

相关文章:

iOS使用Security.framework进行RSA 加密解密签名和验证签名

iOS 上 Security.framework为我们提供了安全方面相关的api; Security框架提供的RSA在iOS上使用的一些小结 支持的RSA keySize 大小有:512,768,1024,2048位支持的RSA 填充方式有三种:NOPadding,PKCS1,OAEP 三…

Android APK反编译详解(附图)

这段时间在学Android应用开发,在想既然是用Java开发的应该很好反编译从而得到源代码吧,google了一下,确实很简单,以下是我的实践过程。 在此郑重声明,贴出来的目的不是为了去破解人家的软件,完全是一种学习…

你不知道的18个Python高效编程技巧

来源 | Python编程时光初识Python语言,觉得python满足了我上学时候对编程语言的所有要求。python语言的高效编程技巧让我们这些大学曾经苦逼学了四年c或者c的人,兴奋的不行不行的,终于解脱了。高级语言,如果做不到这样&#xff0c…

Alisql源码编译安装(详细篇)

前言 AliSQL 在 2016 云栖大会宣布开放源代码之后,迅速就获得了广泛的关注,目前(2016-10-27) star 数目已达 1187,欢迎访问 AliSQL GitHub 项目关注。社区反应也非常活跃,在 Issue 中提了不少反馈建议,其中有一部分是和…

如何给DataGrid添加自动增长列

作者: cuike519的专栏 http://blog.csdn.net/cuike519/我想我们都知道在数据库中如何添加自增长列,我们可以将这个自增长列绑定到DataGrid上使得用户方便的知道现在是第几行,今天我介绍一种不用数据库就可以简单显示出自增长列的方法&…

达摩院NLP团队斩获六项世界冠军背后,让AI没有难懂的语言

2018年末,BERT横空出世,它采用自编码对句子进行表示,通过预测掩盖词和上下句之间的关系作为语言模型学习任务,使用更多的数据,更大的模型,在多个自然语言处理(NLP)任务中显著超越之前…

提权巧用RAR.EXE

rar.exe是什么?它就是大名鼎鼎的winrar自带的命令行解压程序。在提权中我们经常要下载各种敏感文件,比如:SU目录。你想一下,如果su目录文件这么多,难道你要一个个的下载??这明显就很麻烦,有了ra…

OSGI企业应用开发(二)Eclipse中搭建Felix运行环境

上篇文章介绍了什么是OSGI以及使用OSGI构建应用的优点,接着介绍了两款常用的OSGI实现,分别为Apache Felix和Equinox,接下来开始介绍如何在Eclipse中使用Apache Felix和Equinox搭建OSGI运行环境。 一、搭建Apache Felix运行环境 上篇文章中介绍…

马斯克脑机接口、BrainOS相继发布,不努力也能有出路了

作者 | 马超责编 | Carol封图 | CSDN 下载自视觉中国在北京时间的8月29日凌晨,钢铁侠埃隆马斯克投资1亿多美元的脑机接口初创公司公司Neuralink(http://www.neurolink.company/)进行了一次现场发布会,展示新一代的脑机接口设备。这…

C语言单向链表的实现

一个简单结点的结构体表示为:struct note{int data; /*数据成员可以是多个不同类型的数据*/struct note *next; /*指针变量成员只能是-个*/}; 一个简单的单向链表的图示1.链表是结构、指针相结合…

Java开发常用Linux命令

1.查找文件 find / -name filename.txt根据名称查找/目录下的filename.txt文件。 find . -name "*.xml"递归查找所有的xml文件 find . -name "*.xml" |xargs grep "hello world"递归查找所有文件内容中包含hello world的xml文件 grep -H spring …

数据库开发基本操作-安装Sql Server 2005出现“性能监视器计数器要求”错误解决方法...

今天在安装SQL Server 2005时,出现“性能监视器计数器要求”错误,因为以前出现过这种错误,得到了解决。今天又又出现这种错误,但并不是很清楚当时的解决办法,所以这次把解决方法记录下来,供自己以后参考&am…

华为昇腾师资培训沙龙·南京场 |华为昇腾 ACL 语言开发实践全程干货来了!看完就实操系列...

自今年疫情以来,AI 技术加速进入了人们的视线,在抗疫过程中发挥了重要作用,产业发展明显提速,我国逐步走出了一条由需求导向引领商业模式创新、市场应用倒逼基础理论和关键技术创新的发展道路,AI 人才的争夺战也正式打…

设计模式之C#实现---Builder

作者:cuike519的专栏 http://blog.csdn.net/cuike519/我们将要介绍一个和它比较像的创建型模式 Builder (至于关于 Builder 的详细内容您可以参考 GOF 的书,在这里不重复了。)。在 GOF 的书里 Builder 的目的是这样的&#xff1…

微信小程序开发之不能使用eval函数的问题

2019独角兽企业重金招聘Python工程师标准>>> 一 eval函数问题 JavaScript中的eval函数是颇受开发者争议的问题之一,问题主要在于其可能导致的不安全性。有关此方面问题,在此不再赘述,读者可能很容易地浏览到许多介绍性文章。 但是…

设计模式之C#实现--FactoryMethod

作者:cuike519的专栏 http://blog.csdn.net/cuike519/工厂方法的目的很明确就是定义一个用来创建对象的接口,但是他不直接创建对象,而由他的子类来创建,这样一来就将创建对象的责任推迟到了该接口的子类中,创建什么类…

美国AI博士指出,自学Python到底能做什么

我见过市面上很多的 Python 讲解教程和书籍,他们大都这样讲 Python 的:先从 Python 的发展历史开始,介绍 Python 的基本语法规则,Python 的 list, dict, tuple 等数据结构,然后再介绍字符串处理和正则表达式&#xff0…

关于微博溯源的后续问题

1、在进行关键词搜索的时候,如何分词,我们不可能用语料库进行匹配,已没有语料可以学习。 2、关于转折点的寻找。目前我们使用高级搜索,从当前时间往前推,根据搜索到微博的条数变化,确定时间发生具体时间&am…

python3的数据类型以及模块的含义

python3的数据类型以及模块的含义购物车转载于:https://blog.51cto.com/11834445/1884901

设计模式之C#实现---- ProtoType

作者: cuike519的专栏 http://blog.csdn.net/cuike519/该模式的意图是:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。那么首先我们应该已经有了一个对象,同时这个对象还支持自我复制(科隆&…

快速排序(二)最后修改

1 //2012-07-162 void quickSort(element list[], int left, int right)//快速排序3 {4 int ileft;5 int jright;6 7 if(i > j) //判断需要i<j8 return;9 10 element templist[i]; 11 12 while(i<j) 13 { 14 while(i<j …

性能超越GPU、FPGA,华人学者提出软件算法架构加速AI实时化

作者 | 王言治&#xff0c;美国东北大学电子与计算机工程系助理教授出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;近年来&#xff0c;机器学习(Machine Learning)领域的研究和发展可谓是与日俱新&#xff0c;各式各样与机器学习相关的研究成果与应用层出不穷&#…

PHP获取毫秒时间戳,利用microtime()函数

PHP获取毫秒时间戳&#xff0c;利用microtime()函数 php本身没有提供返回毫秒数的函数&#xff0c;但提供了一个microtime()函数&#xff0c;借助此函数&#xff0c;可以很容易定义一个返回毫秒数的函数。php的毫秒是没有默认函数的&#xff0c;但提供了一个microtime()函数&am…

.NET中添加控件数组

作者&#xff1a;cuike519的专栏 http://blog.csdn.net/cuike519/添加控件数组 在.NET里面我好像没有找到有关于控件数组的说明,但是前两天偶在网上看到了一篇关于如何在.NET里面实现控件数组的文章(该文章请参看MSDN).记得大学的时候在使用VB的时候使用过控件数组,可是到了…

如何在机器学习的框架里实现隐私保护?

编者按&#xff1a;数据时代&#xff0c;人们从技术中获取便利的同时&#xff0c;也面临着隐私泄露的风险。微软倡导负责任的人工智能&#xff0c;因此机器学习中的隐私保护问题至关重要。本文介绍了目前机器学习中隐私保护领域的最新研究进展&#xff0c;讨论了机密计算、模型…

函数图像轻松画:教你用永中图象

函数图像轻松画&#xff1a;教你用永中图象 函数图像轻松画&#xff1a;教你用永中图象转载于:https://blog.51cto.com/premium/933220

c语言语系的命名风格和java系命名风格

c语言系的命名风格&#xff1a;单词之间使用下划线分隔。如上图。 java语言是另外一个系&#xff0c;javascript属于java语系(当年就是想借助java的名气所以命名javascript)。java语系是驼峰式命名法&#xff0c;如getElementById()。如果使用c语系命名风格则使用下划线分隔 ge…

全国IP地址分配表

xa.sn.cn,西安公众网,西安,陕西,CN,202.100.0.* xa.sn.cn,西安公众网,西安,陕西,CN,202.100.1.* xa.sn.cn,西安公众网,西安,陕西,CN,202.100.2.* xa.sn.cn,西安公众网,西安,陕西,CN,202.100.3.* xa.sn.cn,西安公众网,西安,陕西,CN,202.100.4.* xa.sn.cn,西安公众网,西安,陕西,C…

神同步!美国三地 Tesla 车主,自动驾驶都撞了警车

来源 | HyperAI超神经&#xff08;ID&#xff1a;HyperAI&#xff09;内容概要&#xff1a;上周在美国北卡州发生了一起交通事故&#xff0c;一辆自动驾驶模式下的 Tesla 撞击了停靠在路边的警车&#xff0c;虽未造成人员伤亡&#xff0c;但车辆损毁严重。事故调查中发现&#…

Q币才是腾讯真正的世界级产品

本文受《虚拟货币将是下一个大平台》启发而来。何玺认为&#xff0c;腾讯Q币本身就具有全球化虚拟货币的基因。 日前&#xff0c;有媒体报道了Pocket Change获得了由Google Ventures领投的500万美元A轮融资&#xff0c;使其融资总额达到640万美元。 Pocket Change是一个为Andro…