Home > database >  How to make a button in Dialog close that Dialog (Kotlin)
How to make a button in Dialog close that Dialog (Kotlin)

Time:07-12

I have a custom dialog that's initialized in onCreate() of some Activity. It displays some text and a button. I want the button to close the dialog when clicked. How can I achieve this?

Here's my attempt that fails.

MyActivity.kt

class MyActivity : AppCompatActivity() {
    private lateinit var myDialog: Dialog
    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        myDialog = Dialog(this)
        myDialog.setContentView(R.layout.my_dialog_layout)
        val button = myDialog.findViewById<Button>(R.id.closeButton)
        button.setOnClickListener {
            fun onClick(v: View) {
                myDialog.dismiss()
            }
        }
    }
}

my_dialog_layout.xml (I stripped away some properties)

<androidx.constraintlayout.widget.ConstraintLayout>

    <TextView
        android:text="Some Text" />

    <Button
        android:id="@ id/closeButton"
        android:text="Close Dialog" />

</androidx.constraintlayout.widget.ConstraintLayout>

CodePudding user response:

Just replace

button.setOnClickListener {
    fun onClick(v: View) {
        myDialog.dismiss()
    }
}

with

button.setOnClickListener {
    fun onClick(v: View) {
        myDialog.dismiss()
    }
    onClick(it)
}

or to make it more simple

button.setOnClickListener {
     myDialog.dismiss()          
}

You have declared a nested function onClick inside the setOnClickListener lambda. As you have declared a nested function but have not called it inside your Dialog is not getting dismissed because myDialog.dismiss() block is not being executed.

CodePudding user response:

your setOnClickListener has little problem change to

class MyActivity : AppCompatActivity() {
    private lateinit var myDialog: Dialog
    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        myDialog = Dialog(this)
        myDialog.setContentView(R.layout.my_dialog_layout)
        val button = myDialog.findViewById<Button>(R.id.closeButton)
        button.setOnClickListener {
            myDialog.dismiss()
        }
    }
}

the better way to create custom dialog is this

class MyDialog private constructor(
    private val context: Context,
    private val confirm: (() -> Unit)? = null,
) {
    private lateinit var dialog: Dialog

    data class Builder(
        internal val context: Context,
        var confirm: (() -> Unit)? = null,
    ) {
        fun setOnConfirm(confirm: () -> Unit) =
            apply {
                this.confirm = confirm
            }

        fun build() = MyDialog(
            context = context,
            confirm = confirm
        )
    }

    init {
        showMyDialog()
    }

    private fun showMyDialog() {
        dialog = Dialog(context)
        dialog.apply {
            requestWindowFeature(Window.FEATURE_NO_TITLE)
            setCancelable(true)
            setContentView(R.layout.your_dialog)
            findViewById<CardView>(R.id.your_item).setOnClickListener {
                dismiss()
            }
            findViewById<CustomTextView>(R.id.text_yes).setOnClickListener {
                confirm?.invoke()
                dismiss()
            }
            window!!.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
            val lp = WindowManager.LayoutParams()
            lp.copyFrom(dialog.window!!.attributes)
            lp.width = context.resources.getDimension(R.dimen.size_320).toInt()
            lp.height = WindowManager.LayoutParams.WRAP_CONTENT
            show()
            window!!.attributes = lp
        }
    }
}

and you can use this class like this

MyDialog.Builder(context = mainActivity, confirm = {
    Log.e("hamid fathi", "Press confirm (yes) button: ", )
}).build()
  • Related