我一直在研究这个应用程序,但遇到了一个我一直无法弄清楚的问题。我有一个listview,其中填充了适配器中的内容,每行都有其特定信息(Uniform)。当我尝试检索在该特定行中找到的复选框的值时,问题就出现了。
有问题的代码如下:
我构建了一个AlertDialog对象,以便我可以从用户那里获取我的信息。我的布局代码包含一个水平方向的LinearLayout,其中包含3个元素,一个图像,文本,复选框。我使用R.layout.listview_layout
构建了我的AlertDialog,这是我制作的自定义布局。
我尝试做的一件事是从适配器获取CheckBox视图;当我通过cb.isChecked()查看它时,无论我在哪一行,它总是未经检查(也就是假)。为了进一步调试,我使用相同的适配器并通过相同的方法检索文本,并返回有关该行的特定信息。
我有什么想法可以解决这个问题吗?
简单地说:
我只想在每个给定的行中获取CheckBox的值
c = help.returnContacts();
AlertDialog.Builder ab = new AlertDialog.Builder(this);
ab.setTitle("Select contacts");
final SimpleCursorAdapter adapter = new SimpleCursorAdapter(
getApplicationContext(), R.layout.listview_layout, c,
new String[] { ClientOpenDbHelperUtility.COL_NAME,
ClientOpenDbHelperUtility.COL_SEL }, new int[] {
R.id.txt_name, R.id.cb_select });
ab.setAdapter(adapter, null);
ab.setPositiveButton("Confirm", new Dialog.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Cursor c = adapter.getCursor();
for (int i = 0; i < adapter.getCount(); i++) {
CheckBox cb = (CheckBox) adapter.getView(i, null, null)
.findViewById(R.id.cb_select);
TextView t = (TextView) adapter.getView(i, null, null)
.findViewById(R.id.txt_name);
Log.d("DEBUG", "Checked = " + cb.isChecked());
Log.d("DEBUG", "Message = " + t.getText().toString());
if (cb.isChecked()) {
help
.updateSelection(
c
.getColumnIndex(ClientOpenDbHelperUtility.COL_UID),
true);
} else {
help
.updateSelection(
c
.getColumnIndex(ClientOpenDbHelperUtility.COL_UID),
false);
}
}
c.close();
help.closeAll();
}
});
ab.show();
}
AlertDialog.Builder ab = new AlertDialog.Builder(this);
ab.setTitle("Select contacts");
final SimpleCursorAdapter adapter = new SimpleCursorAdapter(
getApplicationContext(), R.layout.listview_layout, c,
new String[] { ClientOpenDbHelperUtility.COL_NAME,
ClientOpenDbHelperUtility.COL_SEL }, new int[] {
R.id.txt_name, R.id.cb_select });
ab.setAdapter(adapter, null);
ab.setPositiveButton("Confirm", new Dialog.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Cursor c = adapter.getCursor();
for (int i = 0; i < adapter.getCount(); i++) {
CheckBox cb = (CheckBox) adapter.getView(i, null, null)
.findViewById(R.id.cb_select);
TextView t = (TextView) adapter.getView(i, null, null)
.findViewById(R.id.txt_name);
Log.d("DEBUG", "Checked = " + cb.isChecked());
Log.d("DEBUG", "Message = " + t.getText().toString());
if (cb.isChecked()) {
help
.updateSelection(
c
.getColumnIndex(ClientOpenDbHelperUtility.COL_UID),
true);
} else {
help
.updateSelection(
c
.getColumnIndex(ClientOpenDbHelperUtility.COL_UID),
false);
}
}
c.close();
help.closeAll();
}
});
ab.show();
}
感谢阅读!
答案 0 :(得分:2)
您不应直接致电getView
。这样做会根据数据库的内容生成一个新视图(或回收并覆盖旧视图)。
此外,一旦您的行滚动屏幕的顶部或底部,它们将被回收用于出现的新行。在调用onClick
方法时,您的所有数据,但当前可见的行最有可能已经消失。
您有两种选择:
立即保留对数据库的更改 - 在复选框或行上设置OnClickListener
,并在每次点击活动时更新数据库。
保存对实例变量的更改,然后稍后再应用 - 为您的活动定义Map<Integer, Boolean> changes
实例变量,并在出现点击时调用changes.put(position, isChecked)
。然后,当您的用户点击“应用”或您onClick
的任何内容时,请浏览changes
并将每个人保留到数据库中。它与你现在的基本相同,只是你会使用一个稳定的对象来存储未保存的更改。