Android:ListView之ViewHolder
前言
在开发Android应用过程中经常要与列表展示打交道,比如Listview。在使用过程中如果不能正确的进行细节处理那么对性能还是有很大的损耗的。
Listview展示内容是通过一个Adapter来进行内容绑定的。如下所示:
class Adapter implements ListAdapter{
@Override
public void registerDataSetObserver(DataSetObserver observer) {
}
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {
}
@Override
public int getCount() {
return items.size();
}
@Override
public Object getItem(int position) {
return items.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder vh =null;
if(convertView==null){
vh = new ViewHolder();
convertView = mInflater.inflate(R.layout.item, null);
vh.tv = (TextView) convertView.findViewById(R.id.tvShow);
convertView.setTag(vh);
}else{
vh = (ViewHolder) convertView.getTag();
}
vh.tv.setText(items.get(position));
return convertView;
}
@Override
public int getItemViewType(int position) {
return 1;
}
@Override
public int getViewTypeCount() {
return 1;
}
@Override
public boolean isEmpty() {
return false;
}
@Override
public boolean areAllItemsEnabled() {
return false;
}
@Override
public boolean isEnabled(int position) {
return true;
}
}
有了这个Adapter就可以与Listview进行数据绑定了,如下所示:
lv.setAdapter(new Adapter());
getViw
在Adapter类中有一个重要的实现方法getView用来实现大部分的逻辑,这个就是这篇文章的重点。
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder vh =null;
if(convertView==null){
vh = new ViewHolder();
convertView = mInflater.inflate(R.layout.item, null);
vh.tv = (TextView) convertView.findViewById(R.id.tvShow);
convertView.setTag(vh);
}else{
vh = (ViewHolder) convertView.getTag();
}
vh.tv.setText(items.get(position));
return convertView;
}
先看下这个方法的官方解释
Get a View that displays the data at the specified position in the data set.
You can either create a View manually or inflate it from an XML layout file.
意思是说:获取一个用来展示数据集中指定位置的数据的视图。可以通过代码或者inflate一个XML文件来获得这个View对象。
Parameters(参数)
position
The position of the item within the adapter's data set of the item whose view we want.
我们要展示的数据集中的数据条目的位置
convertView
The old view to reuse, if possible. Note: You should check that this view is non-null and of an appropriate type before using.
If it is not possible to convert this view to display the correct data, this method can create a new view.
Heterogeneous lists can specify their number of view types, so that this View is always of the right type (see getViewTypeCount()and getItemViewType(int)).
一个能用就用的旧视图。注意:在使用之前你需要去检查这个视图是否非空以及其类型。
如果这个视图不能用来正确展示数据,那么此方法就需要创建一个新的视图了。
如果一个列表中有多种视图类型,那么也可以通过getViewTypeCount\getItemViewType方法来正确使用。
parent
The parent that this view will eventually be attached to
这个视图要被添加到的对象
convertView
上一段提到了convertView的reuse(重利用)的内容,也就是说在创建一个新视图去返回给List 的时候需要先检查下旧的视图对象是否还可以利用,包括去检查是否为空以及类型是否正确等等。当然大部分情况下是可以利用的,因此通过这种方式就降低了每次去创建一个item 的view的性能开销了。
view能够重复利用了,那么view中的对象是不是也能够重利用呢,比如其中的展示文本。当然,这就是这篇文章的标题提到的ViewHolder。
ViewHolder
从字面上理解ViewHolder,a holder of the view,就是一个视图的持有者,持有的内容就是视图的所有指定内容,或者说是绑定内容(下面会提到绑定)。个人理解这个持有的意思,就好比是一个引用或者一个指针,ViewHolder中的内容发生了变化那么对应的view中也会随之发生变化;view中的内容发生了变化那么ViewHolder中也随之发生了变化。这就是所谓的hold吧。下面就看下如果绑定一个ViewHolder。
先要定义一个ViewHolder对象,对象里面的内容就是需要hold的视图的内容,比如List中每一个item就是一个TextView用来展示信息,那么如下所示:
static final class ViewHolder{
TextView tv;
}
Item对象的XML,如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="20dip" > <TextView
android:layout_marginTop="5dip"
android:layout_marginBottom="5dip"
android:id="@+id/tvShow"
android:layout_width="wrap_content"
android:layout_height="wrap_content" /> </LinearLayout>
ViewHolder中的tv就是用来hold Item找那个的tvShow的。
ViewHolder有了,那么下面就进入绑定过程。还是回过头来看下getView那个方法片段。
vh = new ViewHolder();
convertView = mInflater.inflate(R.layout.item, null);
vh.tv = (TextView) convertView.findViewById(R.id.tvShow); convertView.setTag(vh);
先把ViewHolder和convertView两个对象建出来,然后通过vh.tv = (TextView) convertView.findViewById(R.id.tvShow);进行了绑定,这样他们之间就产生了关联。
最后通过convertView.setTag(vh);方法使得View和ViewHolder产生了关联,也就是vh真正成为了convertView这个View的holder。
通过这样的方式,以后如果重利用这个视图,就可以通过vh = (ViewHolder) convertView.getTag();的方法来吧这个Holder拿出来,修改其中的内容就可以通过下面的方式了vh.tv.setText(items.get(position));
这样的话省去了findViwyById这样的查找,降低了开销
后记:
Listview有很多中优化性能的方式,这个算是其中一种。
完整代码:ViewHolderDemo
原文连接:http://www.cnblogs.com/luoaz/p/3734999.html
Android:ListView之ViewHolder的更多相关文章
- 【腾讯Bugly干货分享】Android ListView与RecyclerView对比浅析--缓存机制
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/5811d3e3ab10c62013697408 作者:黄宁源 一,背景 Recy ...
- Android ListView 常用技巧
Android ListView 常用技巧 Android TextView 常用技巧 1.使用ViewHolder提高效率 ViewHolder模式充分利用了ListView的视图缓存机制,避免了每 ...
- Android ListView添加多种类型的ItemView
一般复杂的ListView都会重写BaseAdapter,通过重用convertView来减少inflate,通过setTag()和ViewHolder改变ItemView的内容. 重写BaseAda ...
- Android ListView滑动过程中图片显示重复错乱闪烁问题解决
最新内容建议直接访问原文:Android ListView滑动过程中图片显示重复错乱闪烁问题解决 主要分析Android ListView滚动过程中图片显示重复.错乱.闪烁的原因及解决方法,顺带提及L ...
- Android ListView(Selector 背景图片 全选 Checkbox等按钮)
list_item.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xm ...
- Android listview 的优化
接[Android listview的应用][1] 在我们上一篇[Android listview的应用][1]中,我们的adapter中的getView()方法中每次都将布局重新加载一遍,这样就会导 ...
- android listview需要呈现多个布局
android listview需要呈现多个布局 之前的做法很笨 在getView()方法里面,不仅将viewHolder作为tag属性设置给convertView 还将当前的position作为ta ...
- android ListView优化
android ListView通过优化重用历史缓存实现.listview相应的数据适配器一般使用自己定义BaseAdapter子类,重用历史缓冲区来提高性能. 例如,下面的示例代码演示: 1.lis ...
- [置顶]
android ListView包含Checkbox滑动时状态改变
题外话: 在xamarin android的开发中基本上所有人都会遇到这个小小的坎,的确有点麻烦,当时我也折腾了好一半天,如果你能看到这篇博客,说明你和我当初也是一样的焦灼,如果你想解决掉这个小小的坎 ...
随机推荐
- Samba服务器配置参考链接
一步一学Linux与Windows共享文件Samba(很适合初学者,极力推荐): http://os.51cto.com/art/200709/56395.htm 由最简单的一个例子说起,匿名用户可读 ...
- c++暂停
#include<cstdlib> 加入这个 然后 system("pause");
- Matrix 二维树状数组的第二类应用
Matrix Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 17976 Accepted: 6737 Descripti ...
- Android(java)学习笔记98:关于string类型的面试题
package cn.itcast_02; /* * String s = new String(“hello”)和String s = “hello”;的区别? * 有.前者会创建2个对象,后者创建 ...
- .net 在不同情况下调用带soapheader的webservice的方式
国庆长假到了,本想出去玩玩,无奈自己屌丝一枚,啥都没有,只能自己宅在家里思考思考人生.不过人生还是过于复杂,一时间也想不出个所以然,只能是整理一下在工作中遇到的一些小问题,首先是关于带soaphead ...
- Advanced Installer
Advanced Installer是一款功能强大.可生成符合 MS Windows 认证的 Windows Installer 的 MSI 安装包制作工具,具有友好的图形用户界面,直观而且非常简单的 ...
- Lua垃圾收集
Lua使用基于被内置在Lua某些算法的垃圾收集自动内存管理.可以自动内存管理的结果,作为一个开发者: 没有必要担心的对象分配内存. 无需释放他们时,不再需要可将其设置为nil. Lua使用运行不时收集 ...
- Wince 文本函数和字体应用
好像又进入了一个疲惫期了,晚上状态不好,但是还是想继续更新下博客,继上次分析了wince下设备环境以及怎么绘制相关图像后,,笔者在这片文章中讲到文本函数以及其相关应用.文本输出函数是输出文本的内容,也 ...
- centos6.4搭建lnmp服务(转载)
1.配置防火墙,开启80端口.3306端口vi /etc/sysconfig/iptables-A INPUT -m state --state NEW -m tcp -p tcp --dport 8 ...
- CSE(Corrupted State Exceptions) 严重异常处理办法
原因分析 出现这个问题说明.NET版本至少是4.0,因为微软在.NET 4.0版本中更改了异常处理机制.微软认为catch(Exception)这种写法是不负责任的,程序员应该按照异常严重类别决定程序 ...