
本文的合集已經編著成書,進階Android開發強化實戰,歡迎各位讀友的建議和指導。
在京東即可購買:https://item.jd.com/12385680.html
在Android開發中, ListView是重要的元件, 它以清單形式根據資料的長度, 自适應展示具體内容. 使用者可以自由的定義ListView每一列的布局.
當listview有大量資料需要加載的時候, 會占據記憶體, 影響性能. 這時候就需要按需填充, 并重新使用View, 減少對象的建立.
ListView加載資料都是在getView()方法中進行. 同時, 需要自定義ListView重寫ListAdapter: 如BaseAdapter, SimpleAdapter, CursorAdapter等.
優化ListView加載速度, 要讓convertView比對清單類型, 并最大程度的重用convertView.
getView()的加載方法一般有以下三種方式:
(1) 最慢的加載方式: 每次都重新定義一個View, 并載入布局再加載資料.
public View getView(int position, View convertView, ViewGroup parent) {
View item = mInflater.inflate(R.layout.list_item_icon_text, null);
((TextView) item.findViewById(R.id.text)).setText(DATA[position]);
((ImageView) item.findViewById(R.id.icon)).setImageBitmap(
(position & ) == ? mIcon1 : mIcon2);
return item;
}
(2) 較快的加載方式: 當convertView不為空時, 直接重用convertView, 進而減少不必要的View建立,然後加載資料.
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item, parent, false);
}
((TextView) convertView.findViewById(R.id.text)).setText(DATA[position]);
((ImageView) convertView.findViewById(R.id.icon)).setImageBitmap(
(position & ) == ? mIcon1 : mIcon2);
return convertView;
}
(3) 最快的較方式: 定義一個ViewHolder,将convetView的tag設定為ViewHolder, 不為空時重用ViewHolder即可.
static class ViewHolder {
TextView text;
ImageView icon;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_item_icon_text,
parent, false);
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.text);
holder.icon = (ImageView) convertView.findViewById(R.id.icon);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.text.setText(DATA[position]);
holder.icon.setImageBitmap((position & ) == ? mIcon1 : mIcon2);
return convertView;
}
三種方式的效率對比:

當處理一些耗時的資源加載時, 做到以下幾點, 可使你的加載更快更平滑:
(1) 擴充卡在界面主線程中進行修改
(2) 可以在任何地方擷取資料但應該在另外一個地方請求資料
(3) 在主界面的線程中送出擴充卡的變化并調用notifyDataSetChanged()方法(更新資料源)
标準寫法
package me.chunyu.Pedometer.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
/**
* 資料清單的擴充卡
* <p/>
* Created by wang on 15/8/10.
*/
public class DataListAdapter extends ArrayAdapter<DataListAdapter.DataItem> {
private static class ViewHolder {
ImageView icon;
TextView desc;
TextView data;
}
public DataListAdapter(Context context, ArrayList<DataItem> items) {
super(context, R.layout.item_center_data, items);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
DataItem item = getItem(position);
ViewHolder holder;
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_center_data, parent, false);
holder = new ViewHolder();
holder.icon = (ImageView) convertView.findViewById(R.id.center_iv_item_sort);
holder.desc = (TextView) convertView.findViewById(R.id.center_tv_item_desc);
holder.data = (TextView) convertView.findViewById(R.id.center_tv_item_data);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.icon.setImageResource(item.getResource());
holder.desc.setText(item.getDesc());
holder.data.setText(item.getData());
return convertView;
}
// 資料項
public static class DataItem {
private int mResource;
private String mDesc;
private String mData;
public DataItem(int resource, String desc, String data) {
mResource = resource;
mDesc = desc;
mData = data;
}
public int getResource() {
return mResource;
}
public String getDesc() {
return mDesc;
}
public String getData() {
return mData;
}
}
}