MainActivity.kt
package com.cfsuman.kotlintutorials
import android.app.Activity
import android.content.Context
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.util.TypedValue
import android.view.View
import android.widget.*
import androidx.appcompat.app.AlertDialog
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.textfield.TextInputEditText
import com.google.android.material.textfield.TextInputLayout
class MainActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val context:MainActivity = this
// get the widgets reference from XML layout
val button = findViewById<Button>(R.id.button)
val textView = findViewById<TextView>(R.id.textView)
button.setOnClickListener {
val builder = MaterialAlertDialogBuilder(context)
// dialog title
builder.setTitle("Tell us your name.")
// dialog message view
val constraintLayout = getEditTextLayout(context)
builder.setView(constraintLayout)
val textInputLayout = constraintLayout.
findViewWithTag<TextInputLayout>("textInputLayoutTag")
val textInputEditText = constraintLayout.
findViewWithTag<TextInputEditText>("textInputEditTextTag")
// alert dialog positive button
builder.setPositiveButton("Submit"){dialog,which->
val name = textInputEditText.text
textView.text = "Hello, $name"
}
// alert dialog other buttons
builder.setNegativeButton("No",null)
builder.setNeutralButton("Cancel",null)
// set dialog non cancelable
builder.setCancelable(false)
// finally, create the alert dialog and show it
val dialog = builder.create()
dialog.show()
// initially disable the positive button
dialog.getButton(AlertDialog.BUTTON_POSITIVE).isEnabled = false
// edit text text change listener
textInputEditText.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(p0: Editable?) {
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int,
p2: Int, p3: Int) {
}
override fun onTextChanged(p0: CharSequence?, p1: Int,
p2: Int, p3: Int) {
if (p0.isNullOrBlank()){
textInputLayout.error = "Name is required."
dialog.getButton(AlertDialog.BUTTON_POSITIVE)
.isEnabled = false
}else{
textInputLayout.error = ""
dialog.getButton(AlertDialog.BUTTON_POSITIVE)
.isEnabled = true
}
}
})
}
}
}
// get edit text layout
fun getEditTextLayout(context:Context): ConstraintLayout {
val constraintLayout = ConstraintLayout(context)
val layoutParams = ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.MATCH_PARENT,
ConstraintLayout.LayoutParams.WRAP_CONTENT
)
constraintLayout.layoutParams = layoutParams
constraintLayout.id = View.generateViewId()
val textInputLayout = TextInputLayout(context)
textInputLayout.boxBackgroundMode =
TextInputLayout.BOX_BACKGROUND_OUTLINE
layoutParams.setMargins(
32.toDp(context),
8.toDp(context),
32.toDp(context),
8.toDp(context)
)
textInputLayout.layoutParams = layoutParams
textInputLayout.hint = "Input name"
textInputLayout.id = View.generateViewId()
textInputLayout.tag = "textInputLayoutTag"
val textInputEditText = TextInputEditText(context)
textInputEditText.id = View.generateViewId()
textInputEditText.tag = "textInputEditTextTag"
textInputLayout.addView(textInputEditText)
val constraintSet = ConstraintSet()
constraintSet.clone(constraintLayout)
constraintLayout.addView(textInputLayout)
return constraintLayout
}
// extension method to convert values to dp
fun Int.toDp(context: Context):Int = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
this.toFloat(),
context.resources.displayMetrics
).toInt()
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#DCDCDC"
android:padding="24dp">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Show Dialog"
android:textAllCaps="false"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:fontFamily="sans-serif"
android:textSize="24sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/button" />
</androidx.constraintlayout.widget.ConstraintLayout>
build.gradle dependencies[add]
// Material components
implementation 'com.google.android.material:material:1.6.1'


- kotlin - ConstraintLayout center in parent programmatically
- kotlin - Spinner text size programmatically
- kotlin - Spinner text color programmatically
- kotlin - Spinner text align center right programmatically
- kotlin - Spinner item separator programmatically
- kotlin - Create spinner programmatically
- kotlin - AlertDialog title text color size bold programmatically
- kotlin - AlertDialog title align center programmatically
- kotlin - AlertDialog single choice items
- kotlin - AlertDialog multiple choice