1

I have an AlertDialog that I want to display at least once to the user and then continuously display the dialog to the user even after the user clicks "ok" until a certain condition is met.

Here's the code structure I have so far for the AlertDialog:

do {
    val dialogShow: AlertDialog.Builder = AlertDialog.Builder(this@MainActivity)
    dialogShow.setCancelable(false)

    dialogShow.setMessage("Message")
        .setPositiveButton(
            "ok",
            object : DialogInterface.OnClickListener {
                override fun onClick(dialogInterface: DialogInterface, i: Int) {
                    if (checkCondition()) {
                        conditionMet = true
                    } else {
                        // Keep looping
                    }
                }
            })
        .setNegativeButton(
            "cancel",
            object : DialogInterface.OnClickListener {
                override fun onClick(dialogInterface: DialogInterface, i: Int) {
                    conditionMet = true
                    return
                }
            })

    dialogShow.show()
} while (conditionMet == false)

The problem now that I am facing is the AlertDialog will display once, but then never again. Even if conditionMet = false it still won't continue to display. How do I keep displaying the same AlertDialog in a loop?

Tom Darious
  • 434
  • 6
  • 18
  • 3
    I don't think you actually want this in a loop. Otherwise you're just re-showing the dialog thousands of times a second. What you probably want it to show it again after it gets closed? – Henry Twist May 01 '21 at 18:05
  • @HenryTwist Well yes, but I want to keep it showing until `conditionMet` is set to `true`. Thus, why I wanted to use a loop in the first place. – Tom Darious May 01 '21 at 20:55
  • So you're saying that `conditionMet` is changed from somewhere else other than the code you've included? – Henry Twist May 01 '21 at 20:58
  • @HenryTwist No, it's not changed from somewhere else. Only in the code that I provided (the `if` statement in `setPositiveButton` and `setNegativeButton`) – Tom Darious May 01 '21 at 21:18

2 Answers2

2

By wrapping the show code in a loop, you're showing it continuously. What you probably want to do it re-show the dialog if it is dismissed. So something like this pseudocode:

fun showObtrusiveDialog() {

    ...
    dialog.setPositiveButton {
    
        if(shouldStillBeObtrusive()) showObtrusiveDialog()
        ...
    }.setNegativeButton {

        ...
    }

    dialog.show()
}
Henry Twist
  • 5,666
  • 3
  • 19
  • 44
  • 1
    So instead of wrapping it in a loop, wrap it in a function and call that function? – Tom Darious May 01 '21 at 22:04
  • 1
    Yes exactly. Then you're only showing it again when it is dismissed. – Henry Twist May 01 '21 at 23:37
  • Actually @TomDarious my previous sample didn't take into account the back button being pressed, them clicking outside the dialog etc. so I have updated my answer. – Henry Twist May 01 '21 at 23:50
  • Your new answer does not seem to take into account the 'positive' and 'negative' buttons. The 'negative' button can be clicked once and stop showing the dialog. The 'positive' button however can be shown multiple times until the condition inside the 'positive' button is met. – Tom Darious May 02 '21 at 00:34
  • 1
    Sorry you're right. I thought you still wanted to show the dialog again if they cancelled/dismissed. Updated my answer again. – Henry Twist May 02 '21 at 00:39
0

An alternate way to handle this would be to disable the buttons until you're ready to allow the dialog to be closed by the user. Here's an extension function you could call when your condition changes:

fun AlertDialog.setAllButtonsState(enabled: Boolean) {
    arrayOf(DialogInterface.BUTTON_POSITIVE, DialogInterface.BUTTON_NEGATIVE, DialogInterface.BUTTON_NEUTRAL)
        .forEach { getButton(it)?.setEnabled(enabled) }
}

So you can call this to disabled them before you show it, and call it again when your condition changes. You'll need to keep the dialog in a property so you can access it from wherever your condition is being changed.

Tenfour04
  • 83,111
  • 11
  • 94
  • 154
  • I need to check the condition every time the user clicks either the 'ok' or 'cancel' buttons. Disabling them will not allow for this to occur. – Tom Darious May 02 '21 at 00:36