自定义CursorAdapter和CheckBox状态

时间:2012-05-28 13:58:26

标签: android android-cursoradapter android-cursorloader

我在尝试将suggested CursorAdapter implementation与CursorLoader一起使用时遇到问题。 当我可以通过Cursor为它提供静态数据集时,CursorAdapter工作得很好,但是当我尝试将它与CursorLoader结合时,我遇到了nullpointers的问题。我把它归结为这样一个事实:当我向适配器提供一个游标时,它最初是空的(设置为null,这在处理CursorLoader实现时经常被建议)。 在实例化时,适配器循环遍历光标以确定复选框所处的状态,然后遍历以在各种文本视图和小部件中填充数据。不幸的是,光标在实例化时为空,仅在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;
    }
}

2 个答案:

答案 0 :(得分:1)

复制并粘贴

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

到适配器类中的公共帮助器方法(即public void populateAdapter())。

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

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

答案 1 :(得分:-1)

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