0

I'm doing a method to create a custom AlertDialog in which I can call this method passing text, and listener to open a dialog in everywhere.

My problem is that when I'm use it, I need to call a dismiss in every button of the custom view, but when I call this method the system no need to know anything about the dialog.

So, I need to add a "dismiss" on the passed listener or something like that.

private fun showCustomAlertDialog(context: Context, title: String?, message: String?, positiveButtonClickListener: View.OnClickListener?, negativeButtonClickListener: View.OnClickListener?, neutralButtonClickListener: View.OnClickListener?, positiveText: String?, negativeText: String?, neutralText: String?){

        val layoutInflater: LayoutInflater = layoutInflater
        val alertLayout: View = layoutInflater.inflate(R.layout.layout_dialog, null)
        val tvDialogTitle: TextView = alertLayout.findViewById(R.id.tv_dialog_title)
        val tvDialogDescription: TextView = alertLayout.findViewById(R.id.tv_dialog_description)
        val btnAccept: Button = alertLayout.findViewById(R.id.btn_dialog_accept)
        val btnCancel: Button = alertLayout.findViewById(R.id.btn_dialog_cancel)
        val btnNeutral: Button = alertLayout.findViewById(R.id.btn_dialog_neutral)

        val alertDialog = AlertDialog.Builder(context)

        alertDialog.setCancelable(false)
        alertDialog.setView(alertLayout)
        val dialog = alertDialog.create()

        if (title != null) {
            if(title.isNotEmpty()){
                tvDialogTitle.text = title
            }
        }else{
            tvDialogTitle.text = ""
        }

        if (message != null) {
            if(message.isNotEmpty()){
                tvDialogDescription.text = message
            }
        }else{
            tvDialogDescription.text = ""
        }

        if(neutralButtonClickListener != null && (positiveButtonClickListener == null && negativeButtonClickListener == null)){
            btnAccept.visibility = View.GONE
            btnCancel.visibility = View.GONE
            btnNeutral.visibility = View.VISIBLE

            btnNeutral.setOnClickListener(neutralButtonClickListener)
            if (neutralText != null) {
                if(neutralText.isNotEmpty()){
                    btnNeutral.text = neutralText
                }
            }
        }

        if(neutralButtonClickListener == null && (positiveButtonClickListener != null && negativeButtonClickListener != null)) {
            btnAccept.visibility = View.VISIBLE
            btnCancel.visibility = View.VISIBLE
            btnNeutral.visibility = View.GONE

            btnAccept.setOnClickListener(positiveButtonClickListener)
            btnCancel.setOnClickListener(negativeButtonClickListener)

            if (positiveText != null) {
                if(positiveText.isNotEmpty()){
                    btnAccept.text = positiveText
                }
            }

            if (negativeText != null) {
                if(negativeText.isNotEmpty()){
                    btnCancel.text = negativeText
                }
            }

        }

        dialog.show()

    }

At this moment I don't know how to add a dismiss after doing the listener that I passed. For example:

btnAccept.setOnClickListener(positiveButtonClickListener)

Any advice?

Thank you

AskNilesh
  • 67,701
  • 16
  • 123
  • 163
Víctor Martín
  • 3,352
  • 7
  • 48
  • 94

1 Answers1

2
fun showCustomDialog(
            context: Context,
            title: String?,
            onPositiveButtonClicked: (() -> Unit)? = null,
            onNegativeButtonClicked: (() -> Unit)? = null
        ) {
            val binding =
                LayoutCustomDialogBinding.inflate(LayoutInflater.from(context))

            val alertDialog = MaterialAlertDialogBuilder(context)
                .setView(binding.root)
                .create()

            binding.positiveButton.setOnClickListener {
                 alertDialog.dismiss()
                 onPositiveButtonClicked?.invoke()
            }

            binding.negativeButton.setOnClickListener {
                 alertDialog.dismiss()
                 onNegativeButtonClicked?.invoke()
            }
            
            alertDialog.show()
         }

Usage:

showCustomDialog(
    context = context,
    title = "Title",
    onPositiveButtonClicked = {
        //do your action
    }, 
    onNegativeButtonClicked = {
        //do your action
    }
)
  • 1
    Small advice, it's better to use `{ }` for a default value in a lambda rather than making it nullable and then null. See [this question](https://stackoverflow.com/questions/38784939/null-or-empty-lambda-as-default-value) for details – Ionut Jul 05 '22 at 16:45
  • @lonut Thank you for the advice. I reviewed the answers in the link. But I am confused about using empty lambda instead of null because I can easily handle null with kotlin. – Celil Uysal Jul 05 '22 at 18:25
  • If you make it non-nullable with `onPositiveButtonClicked: () -> Unit = {}` you can simply invoke it as `onPositiveButtonClicked()` instead of `onPositiveButtonClicked?.invoke()`, since it has the same behaviour (does nothing when parameter is omitted). Moreover, you can declare the function as `inline` and the lambdas as `crossinline` for a performance improvement (you can't do that when the lambdas are nullable). – Horațiu Udrea Jul 06 '22 at 07:46
  • Thank you for the advice I will research that too – Celil Uysal Jul 07 '22 at 10:30