安卓開發中ListView控制項是一個使用頻率相當的進階控制項,通常用於展示一系列相似性極高的資料,當資料量極大或布局相當複雜時,ListView的效能最佳化就顯得非常重要。所以在開發中不但功能上要滿足,而且在效能上也不能馬虎。
使用ListView是一個標準的適配器設計模式,ListView把資料、XML布局和Adapter有極地結合在一起完成一系列的展示功能。在ListView的資料展示中,每次滑動ListView都會觸發getView()方法的調用,並且XML定義的布局是在也是在適配器的getView()方法中使用布局載入器LayoutInflater載入,LayoutInflater載入布局是件相當耗資源的事兒,又加之findViewById()方法是一個耗時的操作,由此看出頻繁的inflater()和findViewById()操作會給應用帶來相當嚴重的效能問題,所以ListView的效能最佳化是刻不容緩的,好在Google工程師已經為我們提供了相應的解決方案,ListView的緩衝功能。
看例子之前先看看:
下面就通過一個簡單的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";@Overrideprotected 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 + "");}}@Overridepublic int getCount() {return list.size();}@Overridepublic Object getItem(int position) {return list.get(position);}@Overridepublic long getItemId(int position) {return 0;}@Overridepublic 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對象做為資料存到viewview.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;}}