如何在android对话框窗口中更新多选

时间:2012-04-03 04:04:05

标签: java android checkbox cursor multi-select

我一直无法找到帮助使用游标进行多选的教程。截至目前,我的逻辑按照我想要的方式工作,但复选框不会正确更新。我在俯瞰什么?

return new AlertDialog.Builder(this).setTitle("Items")
            .setMultiChoiceItems(cur, CHECK, EDATE, new DialogInterface.OnMultiChoiceClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int position, boolean checked)
                {
                    DBM.open();
                    AlertDialog AD = (AlertDialog) dialog;
                    ListView list = AD.getListView();
                    list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

                    itemCur = (Cursor) list.getItemAtPosition(position);

                    if (checked)
                    {
                        //update query
                        DBM.setChecked(checkCur.getInt(checkCur.getColumnIndex(ID)), itemId, userId, 1);
                        list.setItemChecked(1, true);
                    } else
                    {
                        DBM.setChecked(checkCur.getInt(checkCur.getColumnIndex(ID)), itemId, userId, 0);
                        list.setItemChecked(1, false);
                    }
                    DBM.close();
                }
            }).setPositiveButton("OK", new DialogButtonClickHandler()).create();

3 个答案:

答案 0 :(得分:0)

android上的对话框无法修改。如果查看源代码,您将看到dialogbuilder将所有演示文稿工作委托给某些组件,并且在创建后您无权访问它们。因此,更改用于构建对话框的组件的状态将不会更新对话框组件。

您可以看到此机制herehere:在警报控制器上调用onCreate后,您无权访问访问控制器。

如果你想实现这一点,最好的方法是重建一个新的活动并给它一个对话主题。

答案 1 :(得分:0)

您可以使用setCursor()方法进行AlertDialog。它很简单,所以你可能不需要教程。

相关的SO问题为here,其文档为here

答案 2 :(得分:0)

因此,在深入研究这个问题并经历了几次不同的迭代后,我终于找到了一个我非常满意的解决方案。随着学校和工作的努力,我没有多少时间在外面工作额外的项目,我现在一直坐在这个解决方案,但无法发布。

我的难题的最后一块是找到changeCursor函数,这解决了旧数据的问题,这些数据不再与要加载的数据库相匹配。我目前的障碍是检查一个盒子所需的时间,从点击到更新有明显的滞后。我发现mutliple记录会在单击时更新。我无法找到这些额外更新的正当理由。

以下是我目前为实现多选工作而实施的代码。这只是对话框代码,对于一个工作演示,我将在GitHub上发布一个项目,以便将其全部付诸实践。 (现已公布,Multiselect Dialog

我是一位相当新的Android开发人员,我的大部分Android知识都是通过在线资源知识自学和学习的。我正在研究一个学校项目,并希望在一个对话框中实现多选,该对话框将使用所选择的选项更新主要活动。请提供任何有关如何改进此建议的建议。

优点:
  - 在装载时正确填充复选框   - 单击检查时更新数据库   - 数据更改后保持显示更新。

缺点:
  - 必须单击复选框才能更新值   - 无法撤消对话框中所做的更改。值保存在onClick上,我还没有想到在用户确认之前临时存储新值的方法   - 单击更新多个记录,有时当选项滚动屏幕值更新

@Override
protected Dialog onCreateDialog(int id)
{
    switch (id) {

    case 0:
        LayoutInflater factory = LayoutInflater.from(this);

        // Setup of the view for the dialog
        final View bindListDialog = factory.inflate(R.layout.multi_list_layout, null);
        multiListView = (ListView) bindListDialog.findViewById(R.id.multiList);

        // Because I do not know how to properly handle an undo in this situation
        // I make the dialog only close if the button is pressed and confirms the changes
        return new AlertDialog.Builder(MultiSelectDemoActivity.this).setTitle(R.string.multiSelectTitle)
                .setCancelable(false).setView(bindListDialog)
                .setPositiveButton(R.string.btnClose, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int whichButton)
                    {
                        updateItemList(); // In my implementation there is a list view
                                          // that shows what has been selected.
                    }
                }).create();
    default:
        return null;
    }
}

private static final boolean ONCREATE = true;
private static final boolean ONUPDATE = false;

private void setupMultiList(Boolean newList)
{
    demoDBM.open();
    multiCur = demoDBM.getList(userId); // Gets all items tied to the user.
    startManagingCursor(multiCur);
    // Uses the cursor to populate a List item with an invisible ID column,
    // a name column, and the checkbox
    demoDBM.close();

    if (newList)
    {
        // Creates a new adapter to populate the list view on the dialog
        multiAdapter = new SimpleCursorAdapter(this, R.layout.check_list_item, multiCur, new String[] { DemoDBM.ID,
                DemoDBM.NAME, DemoDBM.SEL }, new int[] { R.id.itemId, R.id.itemName, R.id.itemCheck });
        multiAdapter.setViewBinder(new MyViewBinder());
        multiListView.setAdapter(multiAdapter);
    } else
    {
        // updates the previously made adapter with the new cursor, without changing position
        multiAdapter.changeCursor(multiCur);
    }
}

@Override
protected void onPrepareDialog(final int id, final Dialog dialog, Bundle args)
{
    setupMultiList(ONCREATE);
}

public class MyViewBinder implements ViewBinder
{
    @Override
    public boolean setViewValue(View view, Cursor cursor, int columnIndex)
    {
        int checkId = cursor.getColumnIndex(DemoDBM.SEL);

        if (columnIndex == checkId)
        {
            CheckBox cb = (CheckBox) view;
            // Sets checkbox to the value in the cursor
            boolean bChecked = (cursor.getInt(checkId) != 0);
            cb.setChecked(bChecked); // Switches the visual checkbox.

            cb.setOnCheckedChangeListener(new MyOnCheckedChangeListener());
            return true;
        }
        return false;
    }
}

public class MyOnCheckedChangeListener implements OnCheckedChangeListener
{
    @Override
    public void onCheckedChanged(CompoundButton checkBox, boolean newVal)
    {
        View item = (View) checkBox.getParent(); // Gets the plain_list_item(Parent) of the Check Box

        // Gets the DB _id value of the row clicked and updates the Database appropriately.
        int itemId = Integer.valueOf(((TextView) item.findViewById(R.id.itemId)).getText().toString());
        demoDBM.open();
        demoDBM.setChecked(itemId, userId, newVal);
        demoDBM.close();

        setupMultiList(ONUPDATE);
    }
}