【问题标题】:Adding a CheckBox to a singlechoice set AlertDialog将 CheckBox 添加到单选集 AlertDialog
【发布时间】:2023-04-02 11:31:02
【问题描述】:

我想在这个标准的 AlertDialog 中添加一个带有单个选择列表的复选框

new AlertDialog.Builder(this)
.setSingleChoiceItems(R.array.difficultyLevel_list, 1, new DialogInterface.OnClickListener() {
    @Override public void onClick(DialogInterface dialog, int which) { level = which; }
})
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
    }
})
.setNegativeButton(android.R.string.cancel, null)
.show();

现在,它显示得很好:

我转而使用自定义布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <CheckBox
        android:id="@+id/levels_keep"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="10dp"
        android:checked="false"
        android:text="@string/levels_keep" />

    <ListView
        android:id="@+id/levels_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:entries="@array/difficultyLevel_list"
        android:choiceMode="singleChoice" />

</LinearLayout>

使用此代码:

LayoutInflater inflater = getLayoutInflater();
final View customView = inflater.inflate(R.layout.dialog_levels, null);
final ListView list = (ListView) customView.findViewById(R.id.levels_list);
final CheckBox keep = (CheckBox) customView.findViewById(R.id.levels_keep);
// list.setSelected(level);
list.setItemChecked(level, true); // Marks the item as checked
list.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        level = position;
    }
});

new AlertDialog.Builder(this)
.setView(customView)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        CheckBox keep = (CheckBox) findViewById(R.id.levels_keep);
        if( keep.isChecked() ) {
            Context context = PlayersActivity.this;
            SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
            Editor editor = sp.edit();
            editor.putString(context.getString(R.string.pref_level_key), String.valueOf(level));
            editor.commit();
        }
    }
})
.setNegativeButton(android.R.string.cancel, null)
.show();

显示(列表可滚动):

有几件事我想不通:

  1. 为什么我在列表中看不到单选按钮?
  2. 如何设置默认选中项?(用解决方案编辑代码)
  3. 如何监听选择的变化?(编辑了代码,因为我找到了怎么做)
  4. 如何在复选框方块和复选框文本之间添加填充。我尝试了 android:paddingLeft 但更糟糕的是,文本和正方形重叠。我试过 android:drawablePadding 没有效果。
  5. 为什么主题变了? (不是很重要,只是好奇)编辑似乎主题颜色都搞砸了,当我点击一个项目时,它的文本颜色变成黑色并“消失”到行的背景中

【问题讨论】:

  • 请不要在您的问题标题前加上Android,因为它只会增加噪音,底部的标签绰绰有余。

标签: android android-layout customization android-alertdialog radiobuttonlist


【解决方案1】:

为什么我在列表中看不到单选按钮?

似乎设置android:entries 属性会使ListView 使用com.android.internal.R.layout.simple_list_item_1 作为布局创建ArrayAdapter。我不知道该布局是否完全复制了android.R.layout.simple_list_item_1 布局,但如果是,那么它只是一个TextView,所以没有CheckBox 可用。

如何设置默认选中项?

如果我上面说的是真的,那么删除entries 属性并在代码中使用android.R.layout.simple_list_item_single_choice 作为行布局为*levels_list* ListView 设置适配器。

如何聆听选择的变化?

在布局中的ListView 上设置OnItemClickListener。

如何在复选框方块和复选框之间添加填充 文本。我尝试了 android:paddingLeft 但更糟糕的是,重叠 文本和正方形。我试过 android:drawablePadding 没有效果。

使用简单的CheckBox 和TextView 而不仅仅是CheckBox,您可以随意放置它们。

为什么主题变了? (不是很重要,只是好奇)

我不确定。首先,正如我在上面所说的,ListView 使用了一个特殊的布局(我不知道它的样式),而且您使用的是自定义视图而不是普通的 ListView 内容,这又可以采用不同的样式.

如果您只想在标题中添加ChekcBox,为什么不在AlertDialog 上直接使用set a custom title 并继续使用setSingleChoiceItems?

由 OP 与解决方案编辑

我在这里发布工作代码,因为它绝对基于 Luksprog 的答案,我想将其标记为答案。这段代码已经过测试并且工作正常。

LayoutInflater inflater = getLayoutInflater();
final View customView = inflater.inflate(R.layout.dialog_levels, null);
final ListView list = (ListView) customView.findViewById(R.id.levels_list);
final CheckBox keep = (CheckBox) customView.findViewById(R.id.levels_keep);
String [] items = getResources().getStringArray(R.array.difficultyLevel_list);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_single_choice, items);
list.setAdapter(adapter);
list.setItemChecked(level, true);
list.setOnItemClickListener(new OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        level = position;
    }
});

new AlertDialog.Builder(this)
.setView(customView)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        MyLog.w(TAG,"Level is " + level);
        if( keep.isChecked() ) {
            Context context = PlayersActivity.this;
            SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
            Editor editor = sp.edit();
            editor.putString(context.getString(R.string.pref_level_key), String.valueOf(level));
            editor.commit();
        }
    }
})
.setNegativeButton(android.R.string.cancel, null)
.show();

【讨论】:

  • 谢谢。复选框不是标题,我把它放在最上面,因为否则,根据设备,它被放置在屏幕之外。而且我必须将所有内容都包裹在垂直滚动中才能到达它。这样,复选框始终可见,并且 ListView 可以根据定义滚动。
  • @ilomambo 如果您还为AlertDialog 设置了标题,我的建议没有用。在代码中为ListView 设置适配器。另外,您不应该在对话框中查找CheckBox,例如:((Dialog) dialog).findViewById(etc)?现在可以了吗?
  • 查看我的最新编辑,我找到了问题 2 和 3 的解决方案,我编辑的代码反映了这一点,它包括获取复选框和列表视图的视图 ID。
  • 是的,我编辑了您的答案以包含工作代码,因此我可以将其标记为已回答。等待编辑接受同行评审接受,当被接受时,我会标记答案。谢谢。
猜你喜欢
  • 2014-02-24
  • 2011-05-18
  • 2011-09-22
  • 2013-02-22
  • 2013-07-06
  • 1970-01-01
  • 1970-01-01
  • 2022-01-03
  • 2015-11-16
相关资源
最近更新 更多