android listview优化

<span style="font-size:24px;">listview是一个很重要的控件,如果真正的想熟悉使用listview也不太容易,虽然项目中很多使用到,而且也做出来了,但并对他十分的了解,还有item和它子控件的点击事件,加载图片时出现的各种问题,今天就讲讲listview的优化,一般在显示很多条目时会使用listview,而listview显示那么多条目时,在屏幕上都是一个个view对象,如果显示1000条数据,那么就要创建1000个view对象,这肯定太消耗内存,那肯定是做了缓存,我们在listview的adapter中有一个getView()方法,这方法中第二个参数convertView就是缓存起来的对象,</span>

新建一个android项目listview,

MainActivity.java

<span style="font-size:24px;">public class MainActivity extends Activity {
	private List<String>  datas;
	private LayoutInflater inflater;
	private Context context;
	private MyAdapter adapter;
	private ListView listview;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_main);
		inflater = LayoutInflater.from(this);
		context = MainActivity.this;
		listview = (ListView) findViewById(R.id.listview);
		initData();
		adapter= new MyAdapter();
		listview.setAdapter(adapter);
	}

	private void initData() {
		datas = new ArrayList<String>();
		for(int i=0;i<50;i++){
			datas.add("测试"+":::::::"+i);
		}
	}
	
	class MyAdapter extends BaseAdapter{

		@Override
		public int getCount() {
			return datas.size();
		}

		@Override
		public Object getItem(int position) {
			return datas.get(position);
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup arg2) {
			View view;
<span style="white-space:pre">			</span>view = inflater.inflate(R.layout.item, null);
<span style="white-space:pre">			</span>TextView tvContent = (TextView) view.findViewById(R.id.tvContent);
<span style="white-space:pre">			</span>ImageView img = (ImageView) view.findViewById(R.id.img);
<span style="white-space:pre">			</span>tvContent.setText(datas.get(position));
<span style="white-space:pre">			</span>ImgTask imgTask = new ImgTask(img);
<span style="white-space:pre">			</span>imgTask.execute(imgUrls.get(position));
<span style="white-space:pre">			</span>return view;
		}
	}
}</span>


这样虽然listview能把数据展示出来,但我们仔细想想,如果我们要展示1000条甚至1万条数据时,getView()方法返回的view对象就要创建1万个view对象,那么对内存是多大的开销和浪费,google这样级别的公司肯定是做了优化的,之前说了在getView()方法中第二个参数converView,这就是缓存起来的view对象,那么这个converView是指哪个对象呢?


converView是指当listview滑动出屏幕的时候,而且至少有一个item完全的滑出屏幕时,

那么这个完全滑出屏幕的view就缓存到了内存,就赋值给了converView,这个时候converView对象就不为你null了,现在getView()方法换个写法

View view;
			if(convertView==null){
				view = inflater.inflate(R.layout.item, null);
			}else{
				view = convertView;
			}
			TextView tvContent = (TextView) view.findViewById(R.id.tvContent);
			ImageView img = (ImageView) view.findViewById(R.id.img);
			tvContent.setText(datas.get(position));
			ImgTask imgTask = new ImgTask(img);
			imgTask.execute(imgUrls.get(position));
			return view;

这样就比之前的优化了点,这个view对象只有当converView对象为null时创建,根据之前讲的,view最多创建的个数,应该是当前listview可见条目的个数或者可见条目的个数+1个,而通过view.findViewById()的一些控件,因为view对象不同而不同,这点一定要知道,因为这会涉及到listview异步加载图片发生错乱等寻找原因的证明,既然优化了view对象创建的次数,是不是代表这个写的很完美,不能再优化了呢?,答案是no,


其实就几行代码,我们发现每次通过view去findViewById()也是浪费时间的,因此我们希望把寻找的id封装起来,在java中封装熟悉肯定是用类封装,那我们就现在用类去封装寻找到的控件id,顺便提一句,id是和view绑定在一起的,因此view也是要存在起来的,先看代码


@Override
		public View getView(int position, View convertView, ViewGroup arg2) {
			ViewHolder viewHolder = null;
			if(convertView==null){
				viewHolder = new ViewHolder();
				convertView = inflater.inflate(R.layout.item, null);
				viewHolder.tvContent = (TextView) convertView.findViewById(R.id.tvContent);
				viewHolder.img = (ImageView) convertView.findViewById(R.id.img);
				convertView.setTag(viewHolder);
			}else{
				viewHolder = (ViewHolder) convertView.getTag();
			}
		
			viewHolder.tvContent.setText(datas.get(position));
			ImgTask imgTask = new ImgTask(viewHolder.img);
			imgTask.execute(imgUrls.get(position));
			return convertView;
		}
		class ViewHolder{
			TextView tvContent;
			ImageView img;
		}
	}

现在发现只有当converView对象为null时,才去加载view,并findViewById(),当converView不为null时,id直接从ViewHolder对象中取就不必要每次都去findViewById(),又是优化了一点点,ViewHolder对象创建的个数和View对象创建个数一样,也就是说创建了多少个View对象就创建了多少个ViewHolder对象,


listview优化讲到此为止!




你可能感兴趣的:(android listview优化)