多 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;
    }
}三、效果图
