我正在尝试制作一个具有分隔符的 ActionBar 微调器。我已经实现了SpinnerAdapter具有 2 种项目视图类型的 a(感谢getViewTypeCount)。问题是我正在convertViews从其他类型发送一些。
这是我的 SpinnerAdapter:
public abstract class SeparatorSpinnerAdapter implements SpinnerAdapter {
    Context mContext;
    List<Object> mData;
    int mSeparatorLayoutResId, mActionBarItemLayoutResId, mDropDownItemLayoutResId, mTextViewResId;
    public static class SpinnerSeparator {
        public int separatorTextResId;
        public SpinnerSeparator(final int resId) {
            separatorTextResId = resId;
        }
    }
    public abstract String getText(int position);
    public SeparatorSpinnerAdapter(final Context ctx, final List<Object> data, final int separatorLayoutResId, final int actionBarItemLayoutResId,
            final int dropDownItemLayoutResId, final int textViewResId) {
        mContext = ctx;
        mData = data;
        mSeparatorLayoutResId = separatorLayoutResId;
        mActionBarItemLayoutResId = actionBarItemLayoutResId;
        mDropDownItemLayoutResId = dropDownItemLayoutResId;
        mTextViewResId = textViewResId;
    }
    protected String getString(final int resId) {
        return mContext.getString(resId);
    }
    @Override
    public void registerDataSetObserver(final DataSetObserver observer) {
    }
    @Override
    public void unregisterDataSetObserver(final DataSetObserver observer) {
    }
    @Override
    public int getCount() {
        if (mData != null) {
            return mData.size();
        }
        return 0;
    }
    @Override
    public Object getItem(final int position) {
        return mData == null ? null : mData.get(position);
    }
    @Override
    public boolean isEmpty() {
        return getCount() == 0;
    }
    @Override
    public long getItemId(final int position) {
        return 0;
    }
    @Override
    public boolean hasStableIds() {
        return false;
    }
    @Override
    public View getView(final int position, final View convertView, final ViewGroup parent) {
        return getView(mActionBarItemLayoutResId, position, convertView, parent);
    }
    public boolean isSeparator(final int position) {
        final Object item = getItem(position);
        if (item != null) {
            return item instanceof SpinnerSeparator;
        }
        return false;
    }
    @Override
    public int getItemViewType(final int position) {
        return isSeparator(position) ? 0 : 1;
    }
    @Override
    public int getViewTypeCount() {
        return 2;
    }
    @Override
    public View getDropDownView(final int position, final View convertView, final ViewGroup parent) {
        return getView(isSeparator(position) ? mSeparatorLayoutResId : mDropDownItemLayoutResId, position, convertView, parent);
    }
    private View getView(final int layoutResId, final int position, final View convertView, final ViewGroup parent) {
        View v;
        Log.i("TAG", "getView #" + position + "\tVT=" + getItemViewType(position) + "\tCV="
                + (convertView == null ? " null  " : convertView.getClass().getSimpleName()) + "\ttext=> " + getText(position));
        if (convertView == null) {
            final LayoutInflater li = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = li.inflate(layoutResId, parent, false);
        } else {
            v = convertView;
        }
        final TextView tv = (TextView) v.findViewById(mTextViewResId);
        if (tv != null) {
            tv.setText(getText(position));
            if (isSeparator(position)) {
                tv.setOnClickListener(null);
                tv.setOnTouchListener(null);
            }
        }
        return v;
    }
}
一种实现:
public class IssuesMainFilterAdapter extends SeparatorSpinnerAdapter {
    public IssuesMainFilterAdapter(final Context ctx, final List<Query> queries, final List<Project> projects) {
        super(ctx, buildDataArray(queries, projects), R.layout.issues_filter_spinner_separator, R.layout.issues_filter_spinner_in_actionbar,
                R.layout.issues_filter_spinner, R.id.issues_filter_spinner_text);
    }
    private static List<Object> buildDataArray(final List<Query> queries, final List<Project> projects) {
        final List<Object> data = new ArrayList<Object>();
        data.add(null); // "ALL"
        data.add(new SpinnerSeparator(R.string.issue_filter_queries));
        data.addAll(queries);
        data.add(new SpinnerSeparator(R.string.issue_filter_projects));
        data.addAll(projects);
        return data;
    }
    @Override
    public String getText(final int position) {
        final Object item = getItem(position);
        if (item == null) {
            return getString(R.string.issue_filter_all);
        } else if (item instanceof Query) {
            return ((Query) item).name;
        } else if (item instanceof Project) {
            return ((Project) item).name;
        } else if (item instanceof SpinnerSeparator) {
            return getString(((SpinnerSeparator) item).separatorTextResId);
        }
        throw new InvalidParameterException("Item has unknown type: " + item);
    }
}
您可能已经注意到,我设置了一个日志行,getView()以便更好地了解发生了什么:
05-06 14:01:28.721 I/TAG( 5879): getView #0 VT=1    CV=TextView text=> ####
05-06 14:01:28.721 I/TAG( 5879): getView #1 VT=0    CV=LinearLayout text=> ####
05-06 14:01:28.729 I/TAG( 5879): getView #2 VT=1    CV=TextView text=> ####
05-06 14:01:28.745 I/TAG( 5879): getView #3 VT=1    CV=TextView text=> ####
05-06 14:01:28.745 I/TAG( 5879): getView #4 VT=0    CV=LinearLayout text=> ####
05-06 14:01:28.745 I/TAG( 5879): getView #5 VT=1    CV=TextView text=> ####
05-06 14:01:28.753 I/TAG( 5879): getView #6 VT=1    CV=TextView text=> ####
05-06 14:01:28.768 I/TAG( 5879): getView #7 VT=1    CV=TextView text=> ####
05-06 14:01:28.768 I/TAG( 5879): getView #8 VT=1    CV=TextView text=> ####
05-06 14:01:28.768 I/TAG( 5879): getView #9 VT=1    CV=TextView text=> ####
05-06 14:01:28.776 I/TAG( 5879): getView #10    VT=1    CV=TextView text=> ####
05-06 14:01:28.792 I/TAG( 5879): getView #11    VT=1    CV=TextView text=> ####
05-06 14:01:32.081 I/TAG( 5879): getView #12    VT=1    CV=TextView text=> ####
05-06 14:01:34.690 I/TAG( 5879): getView #13    VT=1    CV=LinearLayout text=> ####
05-06 14:01:35.573 I/TAG( 5879): getView #14    VT=1    CV=TextView text=> ####
05-06 14:01:37.237 I/TAG( 5879): getView #15    VT=1    CV=TextView text=> ####
您可能已经了解,我对真实项目的布局是 TextViews,而分隔符布局是 LinearLayout。
如您所见,一个“真实”项目(VT=1在日志中,参见项目#13)正在回收一个分隔视图(CV=LinearLayout)。我原以为Android会提供convertView相同类型的a,因此只有在滚动时必须创建相同类型的视图(即另一个分隔符)时才会回收第一个分隔符。