I want to create a custom dialog
in Kotlin. I looked through questions on this theme on Stack Overflow, but I could not find any useful informa
This is the way by which you can create your own dialog with custom layout.
val dialogBuilder = AlertDialog.Builder(context, R.style.AlertDialogTheme)
val inflater = this.layoutInflater
val dialogView = inflater.inflate(R.layout.layout_chat_type_selection, null)
dialogBuilder.setView(dialogView)
val radioGroupChat = dialogView.radio_group_chat
dialogView.radioButton_user_chat.isChecked = true
dialogBuilder.setPositiveButton(getString(R.string.ok_text), object : DialogInterface.OnClickListener {
override fun onClick(dialog: DialogInterface, id: Int) {
when (radioGroupChat.checkedRadioButtonId) {
R.id.radioButton_user_chat -> {
(activity as HomeActivity).replaceFragment(MySkippersFragment.getInstance(isFromChat = true))
}
R.id.radioButton_circle_chat -> {
(activity as HomeActivity).replaceFragment(PickCircleFragment.getInstance(
PickCircleFragment.NEW_CIRCLE_CHAT), true)
}
}
}
})
dialogBuilder.setNegativeButton(getString(R.string.cancel_text), object : DialogInterface.OnClickListener {
override fun onClick(dialog: DialogInterface?, which: Int) {
}
})
val alertDialog = dialogBuilder.create()
alertDialog.show()
If someone wants to show 2 buttons on dialog ( GENERIC SOLUTION ) KOTLIN
fun createCustomTwoButtonDialog(
msg: String, context: Context?
, positiveButtonText: String, negativeButtonText: String,
isCancellable: Boolean,
dialogListener: DialogListener
) {
context?.let { context ->
val builder =
AlertDialog.Builder(context)
builder.setTitle("Your desired title")
builder.setMessage(msg)
builder.setCancelable(isCancellable)
builder.setPositiveButton(positiveButtonText) { dialogInterface: DialogInterface?, i: Int ->
dialogListener.onPositiveClick()
dialogInterface?.dismiss()
}
builder.setNegativeButton(negativeButtonText)
{ dialogInterface: DialogInterface?, i: Int ->
dialogListener.onNegativeClick()
dialogInterface?.dismiss()
}
val alertDialog = builder.create()
alertDialog.show()
}
}
DialogListener is interface with 2 methods onNegativeClick() and onPositiveClick()
Works fine. You can also customize it the way you want.
Main class:
class CustomAlertDialogOneButton( activity: Activity?,
private val alertOneButtonClickListener: OnAlertOneButtonClickListener):Dialog(activity!!) {
private var title = ""
private var text = ""
private var dialogId = -1
private var buttonName = ""
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.custom_alert_one_button_dialog)
setCancelable(false)
this.window?.setBackgroundDrawable(ColorDrawable(android.graphics.Color.TRANSPARENT))
viewsClickListenerInit()
}
override fun onStart() {
initDialog()
super.onStart()
}
private fun fillFields(title: String, text: String?, dialogId: Int, buttonName: String) {
clearDialog()
this.title = title
this.text = text ?: ""
this.dialogId = dialogId
this.buttonName = buttonName
}
private fun clearDialog() {
title = ""
text = ""
}
private fun initDialog() {
if (title.isNotBlank()) {
tvAlertTitle.text = title
}
if (text.isNotBlank()) {
tvAlertText.text = text
}
tvAlertButtonOk.text = buttonName
}
fun show(title: String, text: String?, dialogId: Int = -1, buttonName: String = ResourcesRepository.resources.getString(R.string.ok)) {
fillFields(title, text, dialogId, buttonName)
super.show()
}
private fun viewsClickListenerInit() {
tvAlertButtonOk.setOnClickListener {
alertOneButtonClickListener.okClickListener(dialogId)
dismiss()
}
}}
XML for it: name it likes - custom_alert_one_button_dialog.xml
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="280dp"
android:layout_height="145dp"
android:background="@color/colorWhite"
android:orientation="vertical">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.5" />
<TextView
android:id="@+id/tvAlertTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="24dp"
android:paddingTop="22dp"
android:textAlignment="center"
android:textColor="@color/colorDarkGrey"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tvAlertText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="24dp"
android:paddingTop="13dp"
android:paddingEnd="24dp"
android:paddingBottom="10dp"
android:textColor="@color/colorGrey"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvAlertTitle" />
<TextView
android:id="@+id/tvAlertButtonOk"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="10dp"
android:paddingTop="10dp"
android:paddingEnd="34dp"
android:paddingBottom="18dp"
android:text="@string/ok"
android:textColor="@color/colorDarkGrey"
android:textSize="14sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
Interface for button click listener:
interface OnAlertOneButtonClickListener {
fun okClickListener(dialogId: Int = -1)}
Implementation:
class SomeActivity : AppCompatActivity(), OnAlertOneButtonClickListener {
****
private var customDialogOneButton by lazy {
CustomAlertDialogOneButton(this, this)
}
****
customDialogOneButton.show(
title = "some title",
text = "some text",
dialogId = some int constant,
buttonName = "some button name"
)
****
override fun okClickListener(dialogId: Int) {
when (dialogId) {
some int constant -> {
// call method
}
}
}
You can use below code for a custom Dialog. It's my working code.
private fun showDialog(title: String) {
val dialog = Dialog(activity)
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
dialog.setCancelable(false)
dialog.setContentView(R.layout.custom_layout)
val body = dialog.findViewById(R.id.body) as TextView
body.text = title
val yesBtn = dialog.findViewById(R.id.yesBtn) as Button
val noBtn = dialog.findViewById(R.id.noBtn) as TextView
yesBtn.setOnClickListener {
dialog.dismiss()
}
noBtn.setOnClickListener { dialog.dismiss() }
dialog.show()
}
custom_dialog.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/fitsdk_white_rectangle"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginTop="30dp"
android:layout_marginRight="15dp"
android:layout_marginBottom="30dp"
android:orientation="vertical">
<TextView
android:id="@+id/tvTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/error_timeout_title"
android:textColor="@color/black" />
<TextView
android:id="@+id/tvBody"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:text="@string/error_timeout_body"
android:textColor="@color/black" />
<Button
android:id="@+id/btn_yes"
android:layout_width="100dp"
android:layout_height="30dp"
android:background="@android:color/white"
android:clickable="true"
android:text="Yes"
android:textColor="#5DBCD2"
android:textStyle="bold" />
</LinearLayout>
</FrameLayout>
CustomDialogClass.kt
class CustomDialogClass(context: Context) : Dialog(context) {
init {
setCancelable(false)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
requestWindowFeature(Window.FEATURE_NO_TITLE)
setContentView(R.layout.custom_dialog)
}
}
Below my solution as a kind of "message box". I have not implemented an "OK" button. The message box should close after clicking on it.
Here the layout element (*/layout/message_box.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="300dp"
android:orientation="vertical">
<TextView
android:id="@+id/message_box_header"
android:layout_width="match_parent"
android:layout_height="30dp"
android:textAlignment="center"
android:textSize="20sp" />
<TextView
android:id="@+id/message_box_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:textSize="20sp" />
</LinearLayout>
</LinearLayout>
This function I've implement in a Fragment class. It is written in Kotlin.
fun showMessageBox(text: String){
//Inflate the dialog as custom view
val messageBoxView = LayoutInflater.from(activity).inflate(R.layout.message_box, null)
//AlertDialogBuilder
val messageBoxBuilder = AlertDialog.Builder(activity).setView(messageBoxView)
//setting text values
messageBoxView.message_box_header.text = "This is message header"
messageBoxView.message_box_content.text = "This is message content"
//show dialog
val messageBoxInstance = messageBoxBuilder.show()
//set Listener
messageBoxView.setOnClickListener(){
//close dialog
messageBoxInstance.dismiss()
}
}