Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android ListView item有多重布局

android ListView item有多重布局

編輯:關於Android編程

android的listview的一個關鍵技術就是重繪利用。

public View getView(int position, View convertView, ViewGroup parent) {

return null;

}

從Adatper的getview函數我們可以知道,函數提供了一個convertView的對象,這個對象是我們可以在一個列表中重復利用避免每次getview都進行重繪的關鍵。我們平常使用的都是大多是單個布局的item,所以我們可以通過建立一個holder就可以重復利用同一個結構的item。但是如果我們的布局中需要在列表中出先一些個別的item,他的結構跟別的不一樣。比如第一項,或者最後一項跟其他項不一樣,這時候該怎麼做。很多人說直接通過position來判斷就好了,在不同position的時候使用不同的布局。但是想法是很好的一實踐就發現許多問題。

google官方文檔在關於getview函數的時候有明確的提示,當遇到不同item結構的時候應該怎麼處理只不過沒有詳細的實例。下面就根據自己遇到的問題舉個實例。

google文檔中:

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. Heterogeneous lists can specify their number of view types, so that this View is always of the right type (see getViewTypeCount() and getItemViewType(int)). 也就是說如果你在對convertView操作的時候除了要判斷他是不是為空,在多種布局的時候你還得通過getViewTypeCount()來指定你有幾種布局,和通過getItemViewType()來獲得你當前獲得的是哪種結構的view。為什麼要這麼做,不能用position直接來判斷呢,主要原因是你每次在通過getview獲取到的convertView的時候你無法知道這個時候系統復用了哪個布局的view,這樣你在使用converView的holder 的時候就有可能獲取的不是你想要的holder這個時候,你就有可能報空指針異常之類的錯誤。好了既然知道了原理我們來看下具體的例子。

例子,原型是,第一個item使用了一個布局layout_one,其他所有的item使用的是布局layout_two。

代碼:

在adapter裡面定義幾個常量

private static final int ITEM_LAYOUT_TYPE_COUNT = 2;
private static final int TYPE_ONE= 0;
private static final int TYPE_TWO = 1;

//重寫 getViewTypeCount(), getItemViewType();


@Override
public int getViewTypeCount() {
return ITEM_LAYOUT_TYPE_COUNT;
}

// 當系統通過getview獲取convertView的時候通過getItemViewType()可以獲取到相應position的類型。

@Override
public int getItemViewType(int position) {
if(position == 0) {
return TYPE_ONE;
} else {
return TYPE_TWO ;
}
}


@Override
public View getView(int position, View convertView, ViewGroup parent) {
OneHolder oneHolder = new OneHolder();
TwoHolder twoHolder = new TwoHolder();
int layoutType = getItemViewType(position);
if(TYPE_ONE == layoutType) {
if(null == convertView) {
convertView = (LinearLayout) mLayoutInflater.inflate(R.layout.one_layout, null);
oneHolder.oneButton = (Button)convertView.findViewById(R.id.one_button);
convertView.setTag(oneHolder);
} else {
oneHolder = (OneHolder) convertView.getTag();
}
} else if(TYPE_TWO == layoutType) {
if(null == convertView) {
convertView = (LinearLayout) mLayoutInflater.inflate(R.layout.two_layout, null);
twoHolder.twoText = (TextView)convertView.findViewById(R.id.two_text);
convertView.setTag(twoHolder);
} else {
twoHolder = (TwoHolder) convertView.getTag();
}
}
return convertView;
}

當然你如果只是單純不利用復用布局,使用position來做判斷選擇不同的布局也是可以的,但是如果你的這個布局不算太大的話是沒太大問題的,但是如果你的布局稍微復雜點,也就是你每次進行滑動的時候系統會進行重繪,這個時候你就會發現界面一卡一卡的。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved