如何在警告对话框中添加复选框

58

目前,当用户打开我的应用程序时,会弹出一个AlertDialog,询问他们是否想升级到专业版。

我需要在AlertDialog中添加一个CheckBox,使得当用户打开应用程序时不再显示AlertDialog

这是我现在的AlertDialog

AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle(" MY_TEXT");
    builder.setMessage(" MY_TEXT ")
           .setCancelable(false)
           .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
               public void onClick(DialogInterface dialog, int id) {
                   Uri uri = Uri.parse("market://details?id=MY_APP_PACKAGE");
                   Intent intent = new Intent (Intent.ACTION_VIEW, uri);
                   startActivity(intent);                          }
           })
           .setNegativeButton("No", new DialogInterface.OnClickListener() {
               public void onClick(DialogInterface dialog, int id) {
                    dialog.cancel();
               }
           }).show();

如何在 AlertDialog 中添加一个 CheckBox,使得当用户打开应用程序时,勾选该选项后就不再显示 AlertDialog

4个回答

107
你需要在AlertDialog.Builder对象上使用setView(View)方法。这将把传入的View放置在消息区域和按钮之间。只需用一个带有 CheckBoxView进行充气并将其传递进去即可。以下是一个示例:

checkbox.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <CheckBox
        android:id="@+id/checkbox"
        style="?android:attr/textAppearanceMedium"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="5dp" />

</FrameLayout>

在您的Activity中编写代码

View checkBoxView = View.inflate(this, R.layout.checkbox, null);
CheckBox checkBox = (CheckBox) checkBoxView.findViewById(R.id.checkbox);
checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

        // Save to shared preferences
    }
});
checkBox.setText("Text to the right of the check box.");

AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle(" MY_TEXT");
    builder.setMessage(" MY_TEXT ")
           .setView(checkBoxView)
           .setCancelable(false)
           .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
               public void onClick(DialogInterface dialog, int id) {
                   Uri uri = Uri.parse("market://details?id=MY_APP_PACKAGE");
                   Intent intent = new Intent (Intent.ACTION_VIEW, uri); 
                   startActivity(intent);                          }
           })
           .setNegativeButton("No", new DialogInterface.OnClickListener() {
               public void onClick(DialogInterface dialog, int id) {
                    dialog.cancel();
               }
           }).show();

2
我认为你需要将findViewById返回的视图转换为CheckBox。除此之外,答案很棒。 - Gallal
2
如果您的文本太长,请尽量避免使用示例XML布局,复选框将被隐藏。 - xDragonZ
你把那个xml文件保存在哪里?是在layouts文件夹还是其他地方?谢谢。哦,它说R.louyouts.checkbox.xml... 噢噢。呵呵。 - Nerdy Bunz
@JasonRobinson 我知道这有点老了,但我想在我的DialogFragment中做类似的事情。然而,View checkBoxView = View.inflate(this, R.layout.checkbox, null);正在产生此错误:"错误:(28,42)错误:不兼容的类型:无法将WifivsDataDialog转换为Context" - James Robert Singleton
现在,如果复选框能与文本对齐就好了。我不想去调整固定值...有人知道怎么做吗? - CaptainCrunch
此方法的滚动已经损坏,当文本太长时,底部部分会被隐藏。 - Marcin Król

18

制作复选框列表的方法是在AlertDialog中使用setMultiChoiceItems

输入图片描述

// Set up the alert builder
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("Choose some animals");

// Add a checkbox list
String[] animals = {"horse", "cow", "camel", "sheep", "goat"};
boolean[] checkedItems = {true, false, false, true, false};
builder.setMultiChoiceItems(animals, checkedItems, new DialogInterface.OnMultiChoiceClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which, boolean isChecked) {
        // The user checked or unchecked a box
    }
});

// Add OK and Cancel buttons
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
        // The user clicked OK
    }
});
builder.setNegativeButton("Cancel", null);

// Create and show the alert dialog
AlertDialog dialog = builder.create();
dialog.show();

这里我硬编码了哪些项目在列表中已经被选中。更可能的情况是,您希望在 ArrayList<Integer> 中跟踪它们。有关更多详细信息,请参见文档示例。如果您始终希望将所有内容设置为未选中,则还可以将已选项目设置为null

对于上下文,如果您在Activity中,则可以使用this

我的详细回答在这里

Kotlin版本

// Set up the alert builder
val builder = AlertDialog.Builder(context)
builder.setTitle("Choose some animals")

// Add a checkbox list
val animals = arrayOf("horse", "cow", "camel", "sheep", "goat")
val checkedItems = booleanArrayOf(true, false, false, true, false)
builder.setMultiChoiceItems(animals, checkedItems) { dialog, which, isChecked ->
    // The user checked or unchecked a box
}

// Add OK and Cancel buttons
builder.setPositiveButton("OK") { dialog, which ->
    // The user clicked OK
}
builder.setNegativeButton("Cancel", null)

// Create and show the alert dialog
val dialog = builder.create()
dialog.show()

不适用于 builder.setMessage("Some Message"); - DragonFire
一开始看起来很不错,但是现在不能再使用“setMessage”了。虽然你可以这样做,但它会删除复选框。所以如果你需要一个带有文本和复选框的对话框,这种方法就不行了。用户在问题中使用了setMessage... - CaptainCrunch

6
您可以使用只包含一个项目的多选列表:
final boolean[] checked = new boolean[] {false};
builder.setMultiChoiceItems(new String[]{"Remember decision"}, checked, new DialogInterface.OnMultiChoiceClickListener() {
               @Override
               public void onClick(DialogInterface dialogInterface, int i, boolean b) {
                   checked[i] = b;
               }
           });

在警告对话框按钮的 OnClick() 中,您可以检查 checked [0] 的值,并将该值保存在您的应用程序的 Sharedpreferences 中:

builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
                   @Override
                   public void onClick(DialogInterface dialogInterface, int i) {
                       if(checked[0]){
                           SharedPreferences.Editor editor = settings.edit();
                           editor.putBoolean("preferences_never_buy_pro", true);
                           editor.apply();
                       }
                       dialog.cancel();

                   }
               });

通过这个选项,你可以决定以后是否再次显示对话框。


2
正常工作,直到添加了 builder.setMessage(...),不幸的是。 - ernazm
如果您在对话框构建器上调用了setMessage,那么这个答案将不起作用。唯一的解决方案是使用setView。 - HendraWD

2

首先您需要定义一个包含消息和复选框的布局,以便在后续视图上禁用警报。然后,您将不再调用builder.setMessage,而是调用:

builder.setView(myAlertViewWithDisablingCheckbox);

当用户点击警告对话框按钮时,您需要检查该复选框是否已被选中,并将该偏好保存在应用的SharedPreferences中。然后您可以使用该偏好来确定是否应再次向用户显示此警告对话框。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接