在使用ListView时遇到了这样一个数组越界的异常:

Theme: themes{default=overlay:com.baranovgroup.nstyle,iconPack:com.baranovgroup.nstyle,fontPkg:com.baranovgroup.nstyle,com.android.systemui=overlay:com.baranovgroup.nstyle,com.android.systemui.navbar=overlay:com.baranovgroup.nstyle}

java.lang.ArrayIndexOutOfBoundsException: length=2; index=2 at

android.widget.AbsListView$RecycleBin.addScrapView(AbsListView.java:6671)

从异常日志上看没有自己的业务代码啊,于是Google一下,才找到原因.

我们在覆写BaseAdapter时可能会覆写以下方法:

@Override
public int getItemViewType(int position) {
    Person person = getItem(position);
    return person == null ? ViewType.MALE
            : (person.getSex() == Person.Sex.MALE ? ViewType.MALE : ViewType.FEMALE);
}

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

这里有个坑,且系统源码注释里面也没说明:

getViewTypeCount的返回值必须大于getItemViewType的返回值的最大值

比如上述代码中Person的性别有2种,那么ViewType最大值等于1.其他类型的至可以小于等于0,但是不能大于1.

interface ViewType {
    int MALE = -1;
    int FEMALE = 1;
}

然而在使用RecyclerView时我们只需要覆写AdaptergetItemViewType方法,且此值没有大小限制.

public class DataAdapter extends BaseAdapter<String, DataAdapter.DataHolder> {


    public DataAdapter(Context context) {
        super(context);
    }

    @Override
    public int getCustomViewType(int position) {
        return 100;
    }

    @Override
    public DataHolder createCustomViewHolder(ViewGroup parent, int viewType) {
        return new DataHolder(parent, R.layout.item_list_view_male);
    }

    @Override
    public void bindCustomViewHolder(DataHolder holder, int position) {
        String data = getItem(position);
        holder.nameTv.setText(data);
    }

    static class DataHolder extends BaseHolder {

        TextView nameTv;

        DataHolder(ViewGroup parent, @LayoutRes int resId) {
            super(parent, resId);
            nameTv = getView(R.id.name_tv);
        }
    }
}