lisView优化(2)

接着上篇点击,我们使用了ListView 的缓存视图方法去节省加载时间,那么今天我们使用视图缓存+ViewHolder的方法来优化ListView

  (1)什么是ViewHolder?   

        我们在使用ViewHolder之前我们先理清楚它的概念,从字面意思来理解它的意思是“视图持有者”,我们可以知道他是跟View有关的一个概念,从google文档的官方定义知道他是一个静态类,一般只有属性没有方法,它的作用就是一个临时存储器,存储视图的一些属性,那么他在ListView中有什么作用呢?

      我们知道ListView在加载列表时候它需要的东西无非就是:列表长度、每一项的列表View,当前项的位置;有了这3个东西我们就能产生一个ListView列表,这个可以从适配器中获得,其中长度其实就是你得到数据的长度,而当前项的位置则由当前加载位置决定的,因此ListView的加载时间和内存消耗主要是在:View的产生上面,而View的优化我们可以从2个方面进行:

    a.View的创建时间的优化,因此尽量的重复利用已经创建好的View

    b.查找View上面控件的优化,一次尽可能的减少findViewById()的使用

 前者我们可以通过convertView==null的判断来减少重复创建View的时间,后者则可以使用静态ViewHolder来减少findViewById()的使用

 (2)实例比较研究

 我们来动手创建一个来试试:

首先我们来自定义一个Adapter,用来作为ListView的适配器:

   

public class ListViewAdapterBas extends BaseAdapter{
	private Context context;
	private List<Map<String,Object>> data;
	/** 
	 * @param context  上下文
	 * @param data  你要加载到ListView上面的数据
	 */
	public ListViewAdapterBas(Context context){
		 List<Map<String,Object>> itemList=new ArrayList<Map<String,Object>>();
			Map<String,Object> mMap=null;
			for(int i=0;i<10000;i++){
				mMap=new HashMap<String,Object>();
				mMap.put("image", R.drawable.two);
				mMap.put("title", "美女:aspen");
				itemList.add(mMap);
			}
		this.context=context;
		this.data=itemList;
	}
	
	static class ViewHolder{
		//此处就是你定义的中包含的 控件 Item
		ImageView image;
		TextView text;
	}
	
	@Override
	public int getCount() {
		//这里就是返回ListView的总长度
		return data.size();
	}

	@Override
	public Object getItem(int arg0) {
		// TODO Auto-generated method stub
		return arg0;//得到当前加载的项
	}

	@Override
	public long getItemId(int arg0) {
		// TODO Auto-generated method stub
		return arg0;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		long startTime = System.nanoTime();
	    ViewHolder holder;
	    LayoutInflater mInflater=LayoutInflater.from(context);
	    //判断是否已经加载过视图了,如果加载过的话就直接使用,如果没有加载的话就重新加载
	    if(convertView==null){
	    	convertView = mInflater.inflate(R.layout.listview_item, null);
	    	holder = new ViewHolder();
	    	holder.image=(ImageView)convertView.findViewById(R.id.image);
	    	holder.text=(TextView)convertView.findViewById(R.id.title);
	    }else{
            holder = (ViewHolder)convertView.getTag();
        }
	    
    	holder.image.setImageResource(Integer.parseInt(data.get(position).get("image").toString()));
        holder.text.setText(data.get(position).get("title").toString());
        // 停止计时
        long endTime = System.nanoTime();
        // 计算耗时
        long val = (endTime - startTime) / 1000L;
        //Log.e("Test", "Position:" + position + ":" + val);
		return convertView;
	}

}
代码分析:viewHolder

static class ViewHolder{
		//此处就是你定义的中包含的 控件 Item
		ImageView image;
		TextView text;
	}
定义了一个ViewHolder,这里面就是我们列表Item的对应控件,一个图片和一个标题,注意是静态的,静态的好处就是节省了实例化所花费的时间,调用速度回更快,不过占用的内存可能会更多。

getView代码

if(convertView==null){
	    	convertView = mInflater.inflate(R.layout.listview_item, null);
	    	holder = new ViewHolder();
	    	holder.image=(ImageView)convertView.findViewById(R.id.image);
	    	holder.text=(TextView)convertView.findViewById(R.id.title);
	    }else{
            holder = (ViewHolder)convertView.getTag();
        }
判断当前的视图是否已经创建,如果创建了就直接加载,就直接使用getTag()来获取视图,另外使用holder避免了重复加载。

最后直接在Activity中引用:

 

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		ListView lv=(ListView)findViewById(R.id.listView1);
		long startTime = System.nanoTime();
		ListViewAdapterBas listViewAd=new ListViewAdapterBas(this);
	    lv.setAdapter(listViewAd) ; 
		//ListViewAdapter.setListViewAdpter(this, lv);
	    // 停止计时
        long endTime = System.nanoTime();
        // 计算耗时
        long val = (endTime - startTime) / 1000L;
        Log.e("总耗时:", "Position:" + val);
		
        
	}

	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

}
我们来看看和前一篇文章对比消耗时间:


从图上可以看出,消耗的时间大概就是viewCach的40%左右的时间,这样大大优化了ListView.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值