0

我有一个包装 a 的适配器,CursorAdapter原因是我需要在行中显示项目(如在 a 中GridView),但如果在下面的面板中单击(需要 a ListView),还需要显示每个项目的详细信息。因此,我没有CursorAdapter直接填充ListView,而是有一个内部适配器:

public class ChallengeAdapter extends BaseAdapter {

    class ChallengeDataAdapter extends CursorAdapter {

        private BaseAdapter mChallengeAdapter;

        public ChallengeDataAdapter(Context context, Cursor cursor, BaseAdapter a) {
            super(context, cursor, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
            mChallengeAdapter = a;
        }

        @Override
        public void bindView(View arg0, Context arg1, Cursor arg2) {
            // TODO Auto-generated method stub

        }

        @Override
        public View newView(Context arg0, Cursor arg1, ViewGroup arg2) {
            // TODO Auto-generated method stub
            return null;
        }

        @Override
        protected void onContentChanged() {
            super.onContentChanged();
            mChallengeAdapter.notifyDataSetChanged();
        }

    }

    private ChallengeDataAdapter mDataAdapter;

    public ChallengeAdapter(Context context, Cursor cursor) {
        mDataAdapter = new ChallengeDataAdapter(context, cursor, this);
    }

    @Override
    public int getCount() {
        return (mDataAdapter.getCount() + ChallengeMultiTile.ROW_SIZE - 1) / ChallengeMultiTile.ROW_SIZE; //integer divide rounds down
    }

    @Override
    public Object getItem(int position) {
        Challenge[] output = new Challenge[ChallengeMultiTile.ROW_SIZE];
        int min = position * ChallengeMultiTile.ROW_SIZE;
        int max = Math.min(position * ChallengeMultiTile.ROW_SIZE + ChallengeMultiTile.ROW_SIZE, mDataAdapter.getCount());
        for(int i=min; i<max; ++i) {
            output[i-min] = Challenge.get((Cursor) mDataAdapter.getItem(i));
        }
        return output;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if(convertView==null) {
            convertView = new ChallengeMultiTile(parent.getContext());
        }
        ((ChallengeMultiTile) convertView).populate((Challenge[]) getItem(position));
        convertView.setBackgroundColor(0xfffffff);
        return convertView;
    }

    public void swapCursor(Cursor cursor) {
        mDataAdapter.swapCursor(cursor);
        notifyDataSetChanged();
    }

}

这短暂地起作用,但随后ChallengeDataAdapter开始具有getCount()零。但是,我在那里放了一个断点,并且ChallengeDataAdapter#mCursor.getCount()是 6。我把它困在了onContentChanged()方法中,但我不确定它是在哪里发生的。

CursorAdapter当内部光标的计数为六时,为什么计数为零?

4

1 回答 1

2

当您查看 CursorAdapter 源代码时,您会看到 getCount() 和 onContentChanged() 的以下内容:

public int getCount() {
    if (mDataValid && mCursor != null) {
        return mCursor.getCount();
    } else {
        return 0;
    }
}

protected void onContentChanged() {
    if (mAutoRequery && mCursor != null && !mCursor.isClosed()) {
        if (false) Log.v("Cursor", "Auto requerying " + mCursor + " due to update");
        mDataValid = mCursor.requery();
    }
}

因此,虽然 mCursor.getCount() 可能返回 6,但如果重新查询失败, getCount() 可能返回 0。为什么重新查询失败是另一个问题,而不是我可以从您发布的代码中回答的问题。

顺便说一句,您不需要在 ChallengeDataAdapter 类中保留对 ChallengeAdapter 的引用。ChallengeDataAdapter 是一个内部类,它与其封闭类的实例相关联,并且可以直接访问该对象的方法和字段。而不是调用 mChallengeAdapter.notifyDataSetChanged() 你可以做一个 ChallengeAdapter.this.notifyDataSetChanged();

于 2013-04-24T15:57:00.570 回答