多 ViewType 的 BaseAdapter 使用
BaseAdapter可以说是最常用的Adapter了,尤其是它还支持convertView的复用,使得我们的加载View的效率大大提高,然而在实际使用中,存在这样一种情况,ListView中的Item是多种样式的,这样getView()方法中复用的convertView肯定是不同的,那么针对这种情况,我们如何实现convertView的复用呢。其实Android已经考虑到这种情况了,甚至在第一版的API中就为这种情况提供了解决方案,详见下文。
一、关键方法介绍
1.getViewTypeCount ()
- 返回值类型:int
- 返回值:当前BaseAdapter中View类型的总数
- 参考:API文档
1.getItemViewType (int position)
- 返回值类型:int
- 返回值:一个表示View类型的int值。如果多个view可以在getView()方法中被互相转换(converted),那么这些view应该是相同的类型,返回相同的类型值。(注意:类型值应该是
0
至getViewTypeCount()-1
之间的一个值,也可以返回常量IGNORE_ITEM_VIEW_TYPE:-1) - 参考:API文档
二、代码实现
三个布局文件
list_item_red.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FF0000"
android:orientation="vertical" >
<TextView
android:id="@+id/list_item_red_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp" />
</LinearLayout>
list_item_green.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00FF00"
android:orientation="vertical" >
<TextView
android:id="@+id/list_item_green_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp" />
</LinearLayout>
list_item_blue.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#0000FF"
android:orientation="vertical" >
<TextView
android:id="@+id/list_item_blue_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp" />
</LinearLayout>
核心类:MultiTypeBaseAdapter.java
public class MultiTypeBaseAdapter extends BaseAdapter {
public MultiTypeBaseAdapter(int itemCount) {
this.itemCount = itemCount;
}
@Override
public int getCount() {
return itemCount;
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemViewType(int position) {
switch (position % 3) {
case 0:
return RED;
case 1:
return GREEN;
case 2:
return BLUE;
default:
return IGNORE_ITEM_VIEW_TYPE;
}
}
@Override
public int getViewTypeCount() {
return TYPECOUNT;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
int type = getItemViewType(position);
switch (type) {
case RED:
final HolderRed holderRed;
if (convertView == null) {
holderRed = new HolderRed();
convertView = LayoutInflater.from(getApplicationContext()).inflate(R.layout.list_item_red, parent, false);
holderRed.textRed = (TextView) convertView.findViewById(R.id.list_item_red_tv);
convertView.setTag(holderRed);
} else {
holderRed = (HolderRed) convertView.getTag();
}
holderRed.textRed.setText(String.valueOf(position));
break;
case GREEN:
final HolderGreen holderGreen;
if (convertView == null) {
holderGreen = new HolderGreen();
convertView = LayoutInflater.from(getApplicationContext()).inflate(R.layout.list_item_green, parent, false);
holderGreen.textGreen = (TextView) convertView.findViewById(R.id.list_item_green_tv);
convertView.setTag(holderGreen);
} else {
holderGreen = (HolderGreen) convertView.getTag();
}
holderGreen.textGreen.setVisibility(View.INVISIBLE);
break;
case BLUE:
final HolderBlue holderBlue;
if (convertView == null) {
holderBlue = new HolderBlue();
convertView = LayoutInflater.from(getApplicationContext()).inflate(R.layout.list_item_blue, parent, false);
holderBlue.textBlue = (TextView) convertView.findViewById(R.id.list_item_blue_tv);
convertView.setTag(holderBlue);
} else {
holderBlue = (HolderBlue) convertView.getTag();
}
holderBlue.textBlue.setVisibility(View.GONE);
break;
}
return convertView;
}
private int itemCount;
private static final int TYPECOUNT = 3;// 类型总数
// 三种类型,对应类型值应为0至TYPECOUNT-1
private static final int RED = 0;
private static final int GREEN = 1;
private static final int BLUE = 2;
private final class HolderRed {
TextView textRed;
}
private final class HolderGreen {
TextView textGreen;
}
private final class HolderBlue {
TextView textBlue;
}
}