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的开发中基本上所有人都会遇到这个小小的坎,的确有点麻烦,当时我也折腾了好一半天,如果你能看到这篇博客,说明你和我当初也是一样的焦灼,如果你想解决掉这个小小的坎 ...
随机推荐
- PHP做好防盗链的基本思想 防盗链的设置方法
盗链是指服务提供商自己不提供服务的内容,通过技术手段绕过其它有利益的最终用户界面(如广告),直接在自己的网站上向最终用户提供其它服务提供商的服务内容,骗取最终用户的浏览和点击率.受益者不提供资源或提供 ...
- 03 InnoDB锁问题
InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION):二是采用了行级锁.行级锁与表级锁本来就有许多不同之处,另外,事务的引入也带来了一些新问题.下面我们先介绍一点背景知识 ...
- Asp.Net 之 使用Form认证实现用户登录 (LoginView的使用)
1. 创建一个WebSite,新建一个页面命名为SignIn.aspx,然后在页面中添加如下的代码 <div class="div_logView"> <asp: ...
- B. Mr. Kitayuta's Colorful Graph
B. Mr. Kitayuta's Colorful Graph time limit per test 1 second Mr. Kitayuta has just bought an undi ...
- MYSQL基础笔记(六)- 数据类型一
数据类型(列类型) 所谓数据烈性,就是对数据进行统一的分类.从系统角度出发时为了能够使用统一的方式进行管理,更好的利用有限的空间. SQL中讲数据类型分成三大类:1.数值类型,2.字符串类型和时间日期 ...
- 包加载失败 未能正确加载包“xxx”...
打开vs2008或者2005如果弹出一个警告对话框 包加载失败 未能正确加载包“xxx” ...... 的字样,就可以用以下方法解决. 在cmd下运行带参数的devenv.exe: "d(盘 ...
- 获取json对象的id或者根据name获取id
--用json的时候,知道id获取对应的name或者相反根据name获取id --内核代码 <script> var products=[{ID:1,Name:"a", ...
- Adobe Edge Animate –地球自转动画的实现,类似flash遮罩层的效果
Adobe Edge Animate –地球自转动画的实现,类似flash遮罩层的效果 版权声明: 本文版权属于 北京联友天下科技发展有限公司. 转载的时候请注明版权和原文地址. 目前Edge的功能尚 ...
- LeetCode 122
Best Time to Buy and Sell Stock II Say you have an array for which the ith element is the price of a ...
- 【最短路】ACdream 1198 - Transformers' Mission
Problem Description A group of transformers whose leader is Optimus Prime(擎天柱) were assigned a missi ...