zoukankan      html  css  js  c++  java
  • Android性能优化之ListView缓存机制

    要想优化ListView首先要了解它的工作原理,列表的显示须要三个元素:ListView、Adapter、显示的数据。

    这里的Adapter就是用到了适配器模式,无论传入的是什么View在ListView中都能显示出来。


    以下简单说下上图的原理:

    1、假设你有几千几万甚至很多其它的选项(item)时。当中仅仅有可见的项目(满屏显示的Item数目)存在内存(说的优化就是说在内存中的优化!)中,其它的在Recycler中

    2、ListView先请求一个type1视图(getView)然后请求其它可见的项目。convertView在getView中是空(null)的。第一次都是为空的。仅仅要显示过了convertView都不为空,会保存在Recycler中

    3、当item1滚出屏幕。而且一个新的项目从屏幕低端上来时。ListView再请求一个type1视图。

    convertView此时不是空值了,它的值是item1。你仅仅需设定新的数据然后返回convertView,不必又一次创建一个视图,省去了inflate和findViewById的时间,性能就得到了优化。


    了解了它的工作原理后,我们就能够反复利用convertView,仅仅要不为空就直接使用。改变它的内容即可了。

    使用ListView的时候都会搭配一个Adapter,为了使得性能更优。ListView会缓存行item(某行相应的View)。ListView通过Adapter的getView函数获得每行的item。

    package com.dzt.listviewdemo;
    
    import java.util.ArrayList;
    
    import android.app.Activity;
    import android.content.Context;
    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.ImageView;
    import android.widget.ListView;
    import android.widget.TextView;
    
    public class MainActivity extends Activity {
    
    	private ListAdapter adapter;
    	private ListView lv = null;
    	private ArrayList<String> list = new ArrayList<String>();
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		lv = (ListView) findViewById(R.id.lv_list);
    		adapter = new ListAdapter();
    		for (int i = 0; i < 100; i++) {
    			list.add("item " + i);
    		}
    		lv.setAdapter(adapter);
    	}
    
    	private class ListAdapter extends BaseAdapter {
    
    		private LayoutInflater mInflater;
    
    		ListAdapter() {
    			mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    		}
    
    		@Override
    		public int getCount() {
    			// TODO Auto-generated method stub
    			return list.size();
    		}
    
    		@Override
    		public Object getItem(int position) {
    			// TODO Auto-generated method stub
    			return list.get(position);
    		}
    
    		@Override
    		public long getItemId(int position) {
    			// TODO Auto-generated method stub
    			return position;
    		}
    
    		@Override
    		public View getView(int position, View convertView, ViewGroup parent) {
    			// TODO Auto-generated method stub
    			System.out.println("getView " + position + "    " + convertView);
    			viewHolder holder = null;
    			if (convertView == null) {
    				convertView = mInflater.inflate(R.layout.item, null);
    				holder = new viewHolder();
    				holder.text = (TextView) convertView.findViewById(R.id.tv_text);
    				holder.image = (ImageView) convertView
    						.findViewById(R.id.iv_img);
    				convertView.setTag(holder);
    			} else {
    				holder = (viewHolder) convertView.getTag();
    			}
    			holder.text.setText(list.get(position));
    			if (position % 2 == 0) {
    				holder.image.setImageResource(R.drawable.ic_launcher);
    			} else {
    				holder.image.setImageResource(R.drawable.icon);
    			}
    
    			return convertView;
    		}
    
    	}
    
    	/**
    	 * 使用一个类来保存Item中的元素
    	 * 
    	 * @author Administrator
    	 * 
    	 */
    	public static class viewHolder {
    		public TextView text;
    		public ImageView image;
    	}
    }
    
    执行效果


    第一次打印的结果convertView都是为null


    滑动ListView后的打印


    从上面的打印消息能够看出,Recycler中会保存七个convertView对象用来显示Item。无论你有上千个Item,也仅仅会创建显示满屏的convertView。这就大大节省了内存,对viewHolder的Tag的使用也大大节省了性能开销

    相关代码下载:http://download.csdn.net/detail/deng0zhaotai/7842885

  • 相关阅读:
    g++
    Adapter
    使用 JDBC 连接MySQL 、SQL Server数据库
    Chrom Firefox 非安全端口访问
    Cent OS & Windows 双系统自定义引导菜单
    Cent OS 7 安装海峰、极点五笔输入法
    数据结构:单链表
    切记要初始化指针
    Java 连接 MySQL 数据库
    C语言 Struct 结构体在 Java 中的体现
  • 原文地址:https://www.cnblogs.com/cxchanpin/p/6956969.html
Copyright © 2011-2022 走看看