首页 > 解决方案 > 带有 CHOICE_MODE_SINGLE 的 ListView。最多选择一项

问题描述

我在 AlertDialog 中有一个多选列表。

阅读 CHOICE_MODE_SINGLE 的文档,我认为您可以检查一项或检查一项,但对我来说,它的行为就像一个单选按钮列表。它从默认情况下未选中的所有复选框开始,一旦我选中一个,它就不能被取消选中。

我尝试在 onClick 中使用手动 setItemChecked 来破解它,但这不是解决方案。

我究竟做错了什么?如何在 ListView 中实现一个或没有一个复选框?

这是我的代码:

       builder.setMultiChoiceItems(titles,  new boolean[titles.length], new DialogInterface.OnMultiChoiceClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int position, boolean b) {
                if (selectedId == -1) {
                    selectedId = position;
                } else {
                    if (selectedId == position) {
                        mDialog.getListView().setItemChecked(position, false);
                        selectedId = -1;
                    } else {
                        mDialog.getListView().setItemChecked(selectedId, false);
                        selectedId = position;
                    }
                }
            }
        });

        mDialog = builder.create();
        mDialog.getListView().setChoiceMode(AbsListView.CHOICE_MODE_SINGLE);

标签: androidlistview

解决方案


您的代码不起作用,因为您使用的方法 setItemChecked 在收到 false 时不会更改选定状态,并且正在处理 CHOICE_MODE_SINGLE,这是一组单选按钮的正常行为。您可以通过 Android Studio 中的“Go To Implementation”(在方法上按 Ctrl + RightClick)自行查看。

此外,不建议对单选选择器使用复选框,因为它会使您的用户感到困惑。您可以通过 setSingleChoiceItems 轻松获得替换 setMultipleChoiceItems 的单选按钮。它还将单选模式应用于您的 ListView,因此您可以摆脱最后一行。

要允许用户使用单选按钮执行空选择,您主要有 2 个选项:

  • 在您的列表中添加一个额外的项目,代表空选择选项。将其标记为“无”、“取消选中”或类似内容
  • 在对话框中添加一个额外的按钮以关闭对话框并返回一个空选择。

在这里,您有一个实现第一个选项的示例,动态添加空项目以获得更好的可重用性;)

截屏

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    String title = "Select your favourite language";
    String[] items = {"English", "Spanish", "Chinese", "Java"};
    String emptyItemTitle = "NONE OF THEM";
    int initialSelection = 0;

    showSingleChoiceDialogWithNoneOption(title, items, initialSelection, emptyItemTitle);
}

private void showSingleChoiceDialogWithNoneOption(String title, final String[] titleItems, int initialSelection, String emptyItemTitle ) {

    final String[] extendedItems = addEmptyItem(titleItems, emptyItemTitle);
    final int[] selectedPosition = {initialSelection};

    new AlertDialog.Builder(this)
            .setTitle(title)
            .setSingleChoiceItems(extendedItems, initialSelection, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    selectedPosition[0] = which;
                    Log.d("MyTag", String.format("Selected item '%s' at position %s.", extendedItems[which], which));
                }
            })
            .setNegativeButton("Cancel", null)
            .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    Log.d("MyTag", String.format("Confirmed the selection of '%s' at position %s.", extendedItems[selectedPosition[0]], selectedPosition[0]));
                    onSelectionConfirmed(selectedPosition[0]);
                }
            })
            .show();
}

@NonNull
private String[] addEmptyItem(String[] titleItems, String emptyTitle) {
    String[] tempArray = new String[titleItems.length + 1];
    tempArray[0] = emptyTitle;
    System.arraycopy(titleItems, 0, tempArray, 1, titleItems.length);
    return tempArray;
}

private void onSelectionConfirmed(int position) {
    if (position==0){
        //Handle your empty selection
    }else{
        //Selected item at position 
    }
}

}


推荐阅读