1

我在尝试使用建议的 CursorAdapter 实现时遇到问题与 CursorLoader 一起使用。当我可以通过 Cursor 为其提供一组静态数据时,CursorAdapter 工作得很好,但是当我尝试将它与 CursorLoader 结合使用时,我遇到了空指针的问题。我把它归结为这样一个事实,即当我向适配器提供一个游标时,它最初是空的(在处理 CursorLoader 实现时经常建议设置为 null)。适配器在实例化时循环通过光标来确定复选框处于什么状态,然后通过在各种文本视图和小部件中填充数据。不幸的是,光标在实例化时为空,只有在 CursorLoader 完成时才被提供数据集。我试图弄清楚是否可以将此 CursorAdapter 与 CursorLoader 一起使用,并且非常感谢一些帮助。

这是我的完整适配器:

public class ShopperListCursorAdapter extends CursorAdapter implements OnClickListener, LOG {
    private LayoutInflater mInflater;
    private GroceriesHelper mHelper;
    private List<Boolean> mCheckedState;

    public ShopperListCursorAdapter(Context context, Cursor cursor, GroceriesHelper helper, int flags) {
        super(context, cursor, flags);
        mHelper = helper;
        mInflater = LayoutInflater.from(context);
        for(mCheckedState = new ArrayList<Boolean>(); !cursor.isAfterLast(); cursor.moveToNext()) {
            mCheckedState.add(cursor.getInt(cursor.getColumnIndex(Groceries.COLUMN_CHECKED)) != 0);
        }
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        Log.d(TAG, "newView");
        View view = mInflater.inflate(R.layout.listview_row, null);
        ViewHolder holder = new ViewHolder();
        holder.amount = (TextView) view.findViewById(R.id.text_amount);
        holder.unit = (TextView) view.findViewById(R.id.text_unit);
        holder.item = (TextView) view.findViewById(R.id.text_item);
        holder.checked = (CheckBox) view.findViewById(R.id.check_item);
        holder.checked.setOnClickListener(this);
        view.setTag(holder);
        return view;
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        Log.d(TAG, "bindView");
        RowData data = new RowData();
        data.id = cursor.getInt(cursor.getColumnIndex(Groceries.COLUMN_ID));
        data.amount = cursor.getString(cursor.getColumnIndex(Groceries.COLUMN_AMOUNT));
        data.unit = String.valueOf(cursor.getInt(cursor.getColumnIndex(Groceries.COLUMN_UNIT_ID)));
        data.item = cursor.getString(cursor.getColumnIndex(Groceries.COLUMN_ITEM));
        data.position = cursor.getPosition();

        ViewHolder holder = (ViewHolder) view.getTag();
        holder.amount.setText(data.amount);
        holder.unit.setText(data.unit);
        holder.item.setText(data.item);
        holder.checked.setChecked(mCheckedState.get(data.position));
        holder.checked.setTag(data);
    }

    @Override
    public void onClick(View view) {
        boolean visibility = ((CheckBox) view).isChecked();
        RowData data = (RowData) view.getTag();
        Log.d(TAG, "data: " + data.position);
        mCheckedState.set(data.position, visibility);
        mHelper.setChecked(data.id, visibility == true ? 1 : 0);
    }

    private static class ViewHolder {
        TextView amount;
        TextView unit;
        TextView item;
        CheckBox checked;
    }

    private static class RowData {
        int id;
        String amount;
        String unit;
        String item;
        int position;
    }
}
4

2 回答 2

1

复制和粘贴

for(mCheckedState = new ArrayList<Boolean>(); !cursor.isAfterLast(); cursor.moveToNext()) {
    mCheckedState.add(cursor.getInt(cursor.getColumnIndex(Groceries.COLUMN_CHECKED)) != 0);
}

进入适配器类(即public void populateAdapter())中的公共辅助方法。

然后,onLoadFinished在 (with ) 中交换光标,mAdapter.swapCursor(cursor)然后调用mAdapter.populateAdapter(). 这将确保您Cursor在尝试填充之前绑定到适配器mCheckedState

也就是说,我不完全确定你首先要做什么mCheckedState......你为什么不能直接使用Cursorin检查/取消选中视图bindView

于 2012-07-25T02:53:18.333 回答
-1

除非您通知游标,否则即使您的数据库已更新,游标也不会更新。您想要做的是在您的适配器中有一个单独的结构来跟踪单击/未单击状态并参考该结构以获得答案。如果答案不存在,请参考光标(这是您第一次显示列表时的情况)。

于 2012-07-21T18:07:39.367 回答