AlertDialog.Builder访问特定行的问题

时间:2011-03-09 02:16:36

标签: android listview checkbox dialog

我一直在研究这个应用程序,但遇到了一个我一直无法弄清楚的问题。我有一个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(); }

感谢阅读!

1 个答案:

答案 0 :(得分:2)

您不应直接致电getView。这样做会根据数据库的内容生成一个新视图(或回收并覆盖旧视图)。

此外,一旦您的行滚动屏幕的顶部或底部,它们将被回收用于出现的新行。在调用onClick方法时,您的所有数据,但当前可见的行最有可能已经消失。

您有两种选择:

  1. 立即保留对数据库的更改 - 在复选框或行上设置OnClickListener,并在每次点击活动时更新数据库。

  2. 保存对实例变量的更改,然后稍后再应用 - 为您的活动定义Map<Integer, Boolean> changes实例变量,并在出现点击时调用changes.put(position, isChecked)。然后,当您的用户点击“应用”或您onClick的任何内容时,请浏览changes并将每个人保留到数据库中。它与你现在的基本相同,只是你会使用一个稳定的对象来存储未保存的更改。