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