ListView优化-ViewHolder缓存

时间:2021-04-24 22:43:41

        安卓开发中ListView控件是一个使用频率相当的高级控件,通常用于展示一系列相似度极高的数据,当数据量极大或布局相当复杂时,ListView的性能优化就显得非常重要。所以在开发中不但功能上要满足,而且在性能上也不能马虎。
        使用ListView是一个标准的适配器设计模式,ListView把数据、XML布局和Adapter有极地结合在一起完成一系列的展示功能。在ListView的数据展示中,每次滑动ListView都会触发getView()方法的调用,并且XML定义的布局是在也是在适配器的getView()方法中使用布局加载器LayoutInflater加载,LayoutInflater加载布局是件相当耗资源的事儿,又加之findViewById()方法是一个耗时的操作,由此看出频繁的inflater()和findViewById()操作会给应用带来相当严重的性能问题,所以ListView的性能优化是刻不容缓的,好在Google工程师已经为我们提供了相应的解决方案,ListView的缓存功能。
       看例子之前先看看效果图:
ListView优化-ViewHolder缓存

       下面就通过一个简单的Demo来诠释上面的描述。

package com.hitech.convertholderdemo;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity {

	public static final String TAG = "MainActivity";

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		ListView listView = (ListView) findViewById(R.id.lv_activity_main);
		listView.setAdapter(new ListViewDataAdapter());
	}

	private class ListViewDataAdapter extends BaseAdapter {

		private List<String> list = new ArrayList<String>();

		public ListViewDataAdapter() {
			for (int i = 0; i < 100; i++) {
				list.add(i + "");
			}
		}

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

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

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

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			View view = null;
			ViewHolder holder = null;
			if (convertView != null) {
				// 如果convertView中有缓存
				view = convertView;
				// 直接使用缓存并从中取出缓存的ViewHolder对象
				holder = (ViewHolder) view.getTag();
				Log.e(TAG, "使用缓存的convertView" + position);
			} else {
				Log.e(TAG, "没有缓存的convertView" + position);
				// 如果没有缓存,就从XML文件加载布局
				view = getLayoutInflater().inflate(
						R.layout.dialog_popup_main_activity, null);
				// 将加载布局中的控件缓存到ViewHolder中
				holder = new ViewHolder();
				holder.textview_username = (TextView) view
						.findViewById(R.id.textview_username);
				holder.textview_nickname = (TextView) view
						.findViewById(R.id.textview_nickname);
				holder.checkbox_selected = (CheckBox) view
						.findViewById(R.id.checkbox_selected);
				// 把holder对象做为数据存到view
				view.setTag(holder);
			}
			// 对布局中的控件进行设置 由于
			holder.textview_nickname.setText(list.get(position));
			holder.textview_username.setText(list.get(position));
			holder.checkbox_selected.setText(list.get(position));
			return view;
		}
	}

	public static class ViewHolder {
		// 对布局文件中的控件按面向对象思想封装
		TextView textview_username = null;
		TextView textview_nickname = null;
		CheckBox checkbox_selected = null;
	}
}