zoukankan      html  css  js  c++  java
  • 安卓ListView的性能优化

    在安卓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,开启子线程异步处理图片资源。

  • 相关阅读:
    大道至简 第一章 读后随笔
    大道至简 第二章 读后随笔
    动手动脑及实验性练习总结
    大道至简 第三章 阅读心得
    课程作业01 相加运算
    JS函数与BOM
    设备像素,设备独立像素,CSS像素
    斐波那契数列
    JS基础与循环
    吴requests类库 作业总结
  • 原文地址:https://www.cnblogs.com/hainange/p/6334060.html
Copyright © 2011-2022 走看看