58

Currently when the user opens my app, an AlertDialog opens, asking them if they would like to upgrade to the pro version.

I need to add a CheckBox to the AlertDialog that will make the app no longer show the AlertDialog when the user opens the app.

Here is what I have for the AlertDialog now:

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();

How do I add a CheckBox to the AlertDialog that will make the app no longer show the AlertDialog when the user opens the app?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Lucas Faudman
  • 593
  • 1
  • 5
  • 5

4 Answers4

107

You have to use the method setView(View) on the AlertDialog.Builder object. This will put the passed in View between the message area and buttons. Simply inflate a View with a CheckBox and pass that in. Here's an example:

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>

Code in your 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();
Ali Khaki
  • 1,184
  • 1
  • 13
  • 24
Jason Robinson
  • 31,005
  • 19
  • 77
  • 131
  • 2
    I think you need to cast the view returned by findViewById to a CheckBox. Great answer otherwise. – Gallal Apr 15 '14 at 08:52
  • 2
    Try to avoid using long text with the sample xml layut, the checkbox will be hidden if your text is too long – xDragonZ Nov 12 '15 at 12:43
  • Where do you save that xml file? in layouts or somewhere else? thanks. oh it says R.louyouts.checkbox.xml... oops. teehee – Nerdy Bunz May 29 '16 at 11:27
  • @JasonRobinson I know this is kind of old but I am wanting to do a similar thing in my DialogFragment. However, `View checkBoxView = View.inflate(this, R.layout.checkbox, null);` is giving off this error "Error:(28, 42) error: incompatible types: WifivsDataDialog cannot be converted to Context" – James Robert Singleton Aug 11 '16 at 07:37
  • Now, if only the checkbox would be alligned with the text. I don't want to fiddle around with fixed values...anyone? – CaptainCrunch Jul 09 '20 at 21:20
  • Scrolling is broken for this method. Bottom part is hidden when text is too long. – Marcin Król Mar 03 '22 at 11:24
17

Enter image description here

The way to make a checkbox list is to use setMultiChoiceItems in the AlertDialog.

// 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();

Here I hard coded which items in the list were already checked. It is more likely that you would want to keep track of them in an ArrayList<Integer>. See the documentation example for more details. You can also set the checked items to null if you always want everything to start unchecked.

For context, you can use this if you are in an Activity.

My fuller answer is here.

Kotlin version

// 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()
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
  • Does not work with builder.setMessage("Some Message"); – DragonFire Apr 24 '20 at 10:35
  • This looked good at first, but you can't use "setMessage" anymore. You can, but it will delete the checkboxes. So if you need a dialog with text and checkbox this won't work. The user uses setMessage in his question ... – CaptainCrunch Jul 09 '20 at 21:18
6

You could use a multichoicelist with only one item:

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;
               }
           });

Then in the OnClick() of an alert dialog button you can check the value of checked[0]and save that value in your app's 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();

                   }
               });

With this preference you can decide whether the dialog should be shown again in the future.

Jay
  • 3,276
  • 1
  • 28
  • 38
Jannik B
  • 61
  • 1
  • 1
2

First you need to define a layout that contains the message and checkbox for disabling the alert on subsequent views. Then instead of calling builder.setMessage, you'll call:

builder.setView(myAlertViewWithDisablingCheckbox);

Then when the user clicks on the alert dialog button, you'll have to check to see if that checkbox has been checked, and save that preference in your app's SharedPreferences. Then you can use that preference to determine if this alert dialog should be shown to the user again.

Mike Bockus
  • 2,079
  • 17
  • 23