文档章节

安卓ListView的性能优化

htq
 htq
发布于 2016/07/26 09:38
字数 830
阅读 1
收藏 0

在安卓APP中LIstView这个控件可以说基本上是个APP就会用到,但是关于ListView除了需要了解其最基本的用法外,作为一个要做出高性能APP的程序员还需了解一些关于LIstView控件性能优化的基本知识,下面我通过代码一步一步优化的过程来让大家了解LIstView性能优化的相关知识。

一.重用converView:使用LIstView那么你肯定会重写Adapter类中的getView()方法,该方法定义如下:

public View getChildView(int groupPosition, int childPosition,
			boolean isLastChild, View convertView, ViewGroup parent) {}
注意在该方法的第四个参数为converView,通过重用该参数,可以大幅度降低内存消耗,通过判断convertView是否为null来判断是否是第一次加载布局,如果为null则代表是第一次加载该该item,需要重新创建一个,如果不为空,则代表内存中存在该view的实例,只需要重用既可,即直接返回该实例。代码如下:
<pre name="code" class="html">	@Override
	public View getChildView(int groupPosition, int childPosition,
			boolean isLastChild, View convertView, ViewGroup parent) {
		GroupHolder holder = null;
		if (convertView == null) {
			convertView = LayoutInflater.from(mContext).inflate(
					R.layout.fragment_constact_child, null);
			holder = new GroupHolder();
			convertView.setTag(holder);
		} else {
			holder = (GroupHolder) convertView.getTag();
		}
		return convertView;
	}
这样就能够达到重用convertView的效果。

二.使用viewHolder:

上述方式虽然可以重用converView,但是每次都得通过findViewById()来找到布局视图中的控件id,然后来操作这些控件,其实这些操作都是重复的,我们可以定义一个内部类来管理这些控件,然后通过创建该内部类的实例,即可通过该内部类的实例来进行操作这些控件,这样就不用每次都findViewById(),可以减少内存消耗。代码如下:
class GroupHolder {//定义一个内部类来管理该布局视图中需要用到的控件
		TextView nameView;
		TextView feelView;
		ImageView iconView;
	}
@Override
	public View getChildView(int groupPosition, int childPosition,
			boolean isLastChild, View convertView, ViewGroup parent) {
		GroupHolder holder = null;
		if (convertView == null) {
			convertView = LayoutInflater.from(mContext).inflate(
					R.layout.fragment_constact_child, null);
			holder = new GroupHolder();
			holder.nameView = (TextView) convertView
					.findViewById(R.id.contact_list_item_name);
			holder.feelView = (TextView) convertView
					.findViewById(R.id.cpntact_list_item_state);
			holder.iconView = (ImageView) convertView.findViewById(R.id.icon);
			convertView.setTag(holder);
		} else {
			holder = (GroupHolder) convertView.getTag();
		}
holder.nameView.setText(getChild(groupPosition, childPosition)
				.toString());
		holder.feelView.setText("爱生活...爱Android...");
		return convertView;
	}
三 其它方面: 这个主要是如果ListView的布局视图中用到了图片资源时,需要对图片进行处理再加载,具体可以参看我的博客:安卓图片缓存技术,同时请注意使用子线程异步加载,因为图片的加载可能需要消耗一定的时间开销。代码如下;
@Override
	public View getChildView(int groupPosition, int childPosition,
			boolean isLastChild, View convertView, ViewGroup parent) {
		GroupHolder holder = null;
		if (convertView == null) {
			convertView = LayoutInflater.from(mContext).inflate(
					R.layout.fragment_constact_child, null);
			holder = new GroupHolder();
			holder.nameView = (TextView) convertView
					.findViewById(R.id.contact_list_item_name);
			holder.feelView = (TextView) convertView
					.findViewById(R.id.cpntact_list_item_state);
			holder.iconView = (ImageView) convertView.findViewById(R.id.icon);
			convertView.setTag(holder);
		} else {
			holder = (GroupHolder) convertView.getTag();
		}

		String path = childPath[groupPosition][childPosition];
		if (hashMaps.containsKey(path)) {
			holder.iconView.setImageBitmap(hashMaps.get(path).get());
			// 另一个地方缓存释放资源
			ImgUtil.getInstance().reomoveCache(path);
		} else {
			holder.iconView.setTag(path);
			//使用自定义的ImgUtil工具类来异步加载图片资源
			ImgUtil.getInstance().loadBitmap(path, new OnLoadBitmapListener() {
				@Override
				public void loadImage(Bitmap bitmap, String path) {
					ImageView iv = (ImageView) mIphoneTreeView
							.findViewWithTag(path);
					if (bitmap != null && iv != null) {
						bitmap = SystemMethod.toRoundCorner(bitmap, 15);
						iv.setImageBitmap(bitmap);

						if (!hashMaps.containsKey(path)) {
							hashMaps.put(path,
									new SoftReference<Bitmap>(bitmap));
						}
					}
				}
			});

		}
		holder.nameView.setText(getChild(groupPosition, childPosition)
				.toString());
		holder.feelView.setText("爱生活...爱Android...");
		return convertView;
	}
这个版本就是最终优化的代码,即重用converView,使用内部类ViewHolder,开启子线程异步处理图片资源。

本文转载自:http://blog.csdn.net/htq__/article/details/50936666

共有 人打赏支持
htq

htq

粉丝 19
博文 67
码字总数 1007
作品 3
武汉
私信 提问
Android开发优化之——从代码角度进行优化

通常我们写程序,都是在项目计划的压力下完成的,此时完成的代码可以完成具体业务逻辑,但是性能不一定是最优化的。一般来说,优秀的程序员在写完代码之后都会不断的对代码进行重构。重构的好...

KingMing
2015/04/03
0
0
Android ListView优化实践

在看了一些vogella的文章之后,发现关于android listview性能优化这一段很有意思,于是实践了一下,经过优化,性能确实提升不少! 先看看优化前和优化后的比较: 优化前的log截图: 优化后的...

Jerikc
2013/03/23
0
0
Android ListView性能优化之视图缓存

前言 ListView是Android中最常用的控件,通过适配器来进行数据适配然后显示出来,而其性能是个很值得研究的话题。本文与你一起探讨Google I/O提供的优化Adapter方案,欢迎大家交流。 正文 一...

迷途d书童
2012/02/27
457
0
ListView与Adapter使用要点

项目用到ListView,由于要用到ImageView,图片源不是在资源里面的,没法使用资源ID,因此无法直接使用SimpleAdapter,要自己写一个Adapter。在使用ListView和Adapter需要注意以下几点: 1. A...

Taki
2012/08/13
0
0
Android ListView 滑动背景为黑色的解决办法 listview小知识整理

在别的地方看到的,转过来作为记录!! 在Android中,ListView是最常用的一个控件,在做UI设计的时候,很多人希望能够改变一下它的背景,使他能够符合整体的UI设计,改变背景背很简单只需要准备...

假装是大神
2012/12/20
0
0

没有更多内容

加载失败,请刷新页面

加载更多

内存性能的正确解读

一台服务器,不管是物理机还是虚拟机,必不可少的就是内存,内存的性能又是如何来衡量呢。 1. 内存与缓存 现在比较新的CPU一般都有三级缓存,L1 Cache(32KB-256KB),L2 Cache(128KB-2MB)...

阿里云官方博客
6分钟前
0
0
并发+超时示例

func installMantisAgent() {log.Println("begin auto repair mantis agent")num := 0succNum := 0failNum := 0var Q *queue.Queueswitch g.Config().RepairType {ca......

我爱吃葱花
18分钟前
1
0
增加一列自增id

ALTER TABLE xxxx ADD iSiteId INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT FIRST;

colin_86
27分钟前
3
0
安卓代码混淆

Proguard是安卓提供的方便开发者对代码和apk进行保护和精简的工具,可在SDK/tools文件夹下找到。 proguard的作用 : 1,代码混淆 2,精简代码,删掉没有用到的代码,减小apk的体积。 使用场景...

whoisliang
37分钟前
1
0
配置Tomcat虚拟主机

12月13日任务 16.4 配置Tomcat监听80端口 16.5/16.6/16.7 配置Tomcat虚拟主机 16.8 Tomcat日志 配置tomcat监听80端口 默认tomcat监听的是8080端口,如果想直接输入ip就访问到网页,就需要进行...

robertt15
42分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部