CursorAdapter:getCount()== 0,mCu​​rsor.getCount()== 6

时间:2013-04-24 15:14:13

标签: android android-cursoradapter

我有一个包装CursorAdapter的适配器,原因是我需要在行中显示项目(如在GridView中),但如果在下面的面板中单击,还会显示每个项目的详细信息(需要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的{​​{1}}开始为零。但是,我在那里放了一个断点,getCount()是6.我把它困在ChallengeDataAdapter#mCursor.getCount()方法中,但我不确定它是在哪里发生的。

onContentChanged()的内部光标计数为6时,为什么CursorAdapter计数为零?

1 个答案:

答案 0 :(得分: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时,如果requery失败,则getCount()可能返回0。 为什么requery失败是另一个问题,而不是我可以从您发布的代码中回答的问题。

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