Search code examples
androidkotlinbuttondialogdismiss

Avoid AlertDialog auto dismissing when positive button is pressed


I am attempting to prevent the automatic dismissal of a dialog in the else statement in siteListFragment.kt, but despite my efforts, the dialog dismisses on its own.

Here is my code: siteListFragment.kt

override fun showAddSiteDialog() {
        val view: View = LayoutInflater.from(context).inflate(R.layout.dialog_site_add, null)
        DialogService.showWithView(
            requireContext(),
            DialogService.DialogType.INFO,
            false,
            getString(R.string.add_site),
            view,
            null,
            DialogService.TextWithCallback(getString(R.string.dialog_negative_cancel)){
                DialogService.dismiss()
            },
            DialogService.TextWithCallback(getString(R.string.dialog_positive_add)){
                GlobalScope.launch {
                    val editText = view.findViewById<EditText>(R.id.site_name_add)

                    val enteredText = editText.text.toString()
                    withContext(Dispatchers.Main) {
                        if (siteListPresenter.addSite(enteredText)) {
                            DialogService.dismiss()
                        } 
                        
                        //here
                        else {
                            editText.error = getString(R.string.network_update_error_empty_name_message)
                        }
                    }
                }
            }
        )
    }

DialogService.kt

    private var dialog: AlertDialog? = null
    var builder:  AlertDialog.Builder? = null

private fun create(
        context: Context,
        dialogType: DialogType,
        cancelable: Boolean,
        title: String,
        message: String?
        ) {
        builder = AlertDialog.Builder(context, R.style.CreativePodDialog)
        dialog = builder!!.create()
        builder!!.apply {
            setTitle(title)
            setIcon(getIcon(dialogType))

            if (message != null && message != "") setMessage(message)
            setCancelable(cancelable)
        }
    }

fun showWithView(
        context: Context,
        dialogType: DialogType,
        cancelable: Boolean,
        title: String,
        view: View? = null,
        negativeButton: TextWithCallback?,
        neutralButton: TextWithCallback?,
        positiveButton: TextWithCallback?,
    ) {
        create(context, dialogType, cancelable, title, null)

        builder!!.apply {
            setView(view)
            if (positiveButton != null)
                setPositiveButton(positiveButton.text) { _, _ ->
                    positiveButton.callback.invoke()
                }
            if (negativeButton != null)
                setNegativeButton(negativeButton.text) { _, _ ->
                    negativeButton.callback.invoke()
                }
            if (neutralButton != null)
                setNeutralButton(neutralButton.text) { _, _ ->
                    neutralButton.callback.invoke()
                }
        }.show()
    }

I have tried to set the dialog to not cancelable which allows you to press outside the dialog and not have it dismiss but doesnt effect the button. I have also tried to set the dialog positive button callback to null which just defaults to dismissing. Any help would be much appreciated.


Solution

  • AlertDialog by default has View.onClickListeners which will automatically dismiss the dialog once user clicks the positive or negative button.

    To prevent this from happening, you'll have to override the listener yourself.

    val btPositive = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE);
    btPositive.setOnClickListener {
        // do something here
        // dialog won't be dismissed now!
    }
    

    You can pass null callback in the DialogService.TextWithCallback function to make it work as expected.