1. 程式人生 > >Gridview 自定義Adapter及優化

Gridview 自定義Adapter及優化

(1)和上次一樣的GridView和佈局
<GridView
        android:id="@+id/grid"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:numColumns="3"
        ></GridView>
//gridview_item
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/item_img"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

    <TextView
        android:id="@+id/item_text"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

</LinearLayout>
(2)寫MyAdapterextends BaseAdapter
<blockquote>public class MyAdapter extends BaseAdapter {

打好log,然後從日誌裡面看自定義Adapter的作用。



(3)java檔案

ArrayList<String> arrays = new ArrayList<String>();  
        for(int i=0; i<100; i++) {  
            arrays.add("" + i);  
        }  
(4)執行,結果見下圖




向上或者向下滑動都會呼叫getView,也就是一開始出現在視野內的東西,離開之後在回來還是會呼叫getView

優化1:
用convertview
根據一篇博文,(基本參考了這篇)如果是listview的話,在顯示第一屏的item呼叫getView的時候,convertview就會=null,
在往下 翻或者翻回來的時候,convertview就不是null了。
但是gridview可能因為在佈局中是存在一個LinearLayout(但是不確定)(也有可能是之前執行過,快取沒有清,因為之後出來了是null),所以看不出來效果
根據convertview一開始為null的條件可以做出如下優化,
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    Log.d("mark", "getView() is invoked!" + "position = " + position + ","
        + "convertView = " + convertView + "," + "parent = " + parent);
    if (convertView == null) {
       convertView = inflater.inflate(R.layout.gridview_item, null);
    }

    ((ImageView) convertView.findViewById(R.id.image_pic))
        .setImageResource(R.drawable.logo);
    ((TextView) convertView.findViewById(R.id.text_content))
        .setText("logo" + arrays.get(position));

    return convertView;
}
即,把在getview方法中每次新建的view換成了convertview,
那麼,啥是convertview?
convertView The old view to reuse, if possible. Note: You should check that this view is non-null and of an appropriate type before using. If it is not possible to convert this view to display the correct data, this method can create a new view.
文件裡面說是用於重用的view,要保證非空和型別匹配。
也就是開始顯示的時候建立一屏的item是會新建view,之後就是重用之前建立的convertview了

優化2:
用ViewHolder 
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Log.d("mark", "getView() is invoked!" + "position = " + position + ","
+ "convertView = " + convertView + "," + "parent = " + parent);

ViewHolder vHolder = null;
if (convertView == null) {
convertView = inflater.inflate(R.layout.gridview_item, null);
vHolder = new ViewHolder();
vHolder.pic = (ImageView) convertView.findViewById(R.id.item_img);
vHolder.content = (TextView) convertView.findViewById(R.id.item_text);
// 設定 Tag
convertView.setTag(vHolder);
} else {
vHolder = (ViewHolder) convertView.getTag();
}
vHolder.pic.setImageResource(R.drawable.logo);
vHolder.content.setText("logo" + arrays.get(position));
return convertView;
}
static class ViewHolder {//類定義,靜態內部類
TextView content;
ImageView pic;
// 很多view的定義
}
convertview避免了建立新的view並inflate,viewholder通過tag把自己和convertview連起來,
避免了每次都執行findViewById,二者是優化adpter的主要途徑。

最後別忘了,ImageView使用的圖片要預處理。
showIcon = BitmapFactory.decodeResource(context.getResources(), R.drawable.logo);