Android Studio: уроки на Kotlin. AlertDialog.

Диалоговые окна — это небольшие всплывающие подсказки, которые просят пользователя подтвердить действие, выбрать вариант или просто сообщают важную информацию. В этом уроке из цикла Android Studio Kotlin уроки мы научимся создавать их без сторонних библиотек, используя встроенный в Android SDK класс AlertDialog. Вы узнаете, как добавить кнопки, обработать нажатие и не потерять данные при повороте экрана.


Зачем нужны диалоги и какими они бывают

Диалог привлекает внимание пользователя и требует немедленного решения: «Да» или «Нет», «ОК» или «Отмена». Их используют для подтверждения удаления, выбора цвета, ввода пароля или просто для показа сообщения об ошибке. В Android есть несколько способов создать диалог, но мы начнём с самого простого и гибкого — AlertDialog.Builder.


Простейший диалог с одной кнопкой

Создайте в вашей Activity метод, который будет показывать диалог. Внутри него настройте Builder: установите заголовок, текст и кнопку «ОК». При нажатии диалог просто закроется.

private fun showSimpleDialog() {
    AlertDialog.Builder(this)
        .setTitle("Привет!")
        .setMessage("Это ваш первый диалог на Kotlin.")
        .setPositiveButton("ОК") { dialog, _ ->
            dialog.dismiss()
        }
        .show()
}

Вызовите этот метод, например, при клике на кнопку. На экране появится стандартное окно с текстом и одной кнопкой.


Диалог с двумя кнопками: Да/Отмена

Классический сценарий — подтверждение выхода из приложения. Builder позволяет добавить три типа кнопок: положительную, отрицательную и нейтральную. Добавим две: «Да» и «Отмена».

private fun showExitDialog() {
    AlertDialog.Builder(this)
        .setTitle("Выход")
        .setMessage("Вы действительно хотите выйти?")
        .setPositiveButton("Да") { dialog, _ ->
            finish() // закрываем Activity
            dialog.dismiss()
        }
        .setNegativeButton("Отмена") { dialog, _ ->
            dialog.dismiss()
        }
        .show()
}

Теперь пользователь случайно не выйдет — диалог переспросит. Логика каждой кнопки задаётся в лямбде.


Диалог со списком: AlertDialog с пунктами

Иногда нужно предложить выбор из нескольких вариантов. Builder умеет показывать список строк. При тапе по элементу диалог закрывается, а вы получаете индекс выбранного пункта.

val colors = listOf("Красный", "Зелёный", "Синий")

private fun showListDialog() {
    AlertDialog.Builder(this)
        .setTitle("Выберите цвет")
        .setItems(colors.toTypedArray()) { dialog, which ->
            Toast.makeText(this, "Вы выбрали: ${colors[which]}", Toast.LENGTH_SHORT).show()
            dialog.dismiss()
        }
        .show()
}

Здесь which — индекс элемента в массиве. Никаких адаптеров писать не нужно, всё делает Builder.


Диалог с радиокнопками (radio buttons)

Для единственного выбора с сохранением состояния подходит метод setSingleChoiceItems. Вы передаёте массив строк и индекс текущего выбора, а Builder отобразит кружки для отметки.

val sizes = listOf("Маленькая", "Средняя", "Большая")
private var selectedSize = 0

private fun showSingleChoiceDialog() {
    AlertDialog.Builder(this)
        .setTitle("Размер пиццы")
        .setSingleChoiceItems(sizes.toTypedArray(), selectedSize) { dialog, which ->
            selectedSize = which
        }
        .setPositiveButton("Принять") { dialog, _ ->
            Toast.makeText(this, "Выбрано: ${sizes[selectedSize]}", Toast.LENGTH_SHORT).show()
            dialog.dismiss()
        }
        .setNegativeButton("Отмена") { dialog, _ -> dialog.dismiss() }
        .show()
}

Обратите внимание: состояние сохраняется в переменной selectedSize. При следующем открытии диалога кружок будет стоять там, где оставил пользователь.


Собственная разметка в диалоге

Если ни один из стандартных стилей не подходит, можно внедрить в диалог свою XML-разметку. Создайте res/layout/dialog_login.xml с двумя EditText (логин и пароль). Затем укажите его через setView:

val dialogView = layoutInflater.inflate(R.layout.dialog_login, null)
AlertDialog.Builder(this)
    .setTitle("Вход")
    .setView(dialogView)
    .setPositiveButton("Войти") { dialog, _ ->
        val login = dialogView.findViewById<EditText>(R.id.etLogin).text.toString()
        val password = dialogView.findViewById<EditText>(R.id.etPassword).text.toString()
        // обработайте логин и пароль
        dialog.dismiss()
    }
    .setNegativeButton("Отмена") { dialog, _ -> dialog.dismiss() }
    .show()

Теперь у вас полностью кастомный диалог, который можно наполнить любыми View.


Диалог в Jetpack Compose

Если вы используете Compose, там есть компонент AlertDialog. Выглядит он похоже, но все параметры задаются через Composable-функции:

var showDialog by remember { mutableStateOf(false) }

if (showDialog) {
    AlertDialog(
        onDismissRequest = { showDialog = false },
        title = { Text("Удалить запись?") },
        text = { Text("Действие нельзя будет отменить") },
        confirmButton = {
            TextButton(onClick = { showDialog = false }) {
                Text("Удалить")
            }
        },
        dismissButton = {
            TextButton(onClick = { showDialog = false }) {
                Text("Отмена")
            }
        }
    )
}

Всё остальное — кнопки, списки, кастомная вёрстка — тоже делается через Compose-элементы.


Советы для новичков

  • Не злоупотребляйте диалогами. Если показывать их слишком часто, пользователь будет раздражаться.
  • Явно указывайте кнопку отмены. У пользователя всегда должна быть возможность отказаться от действия, даже если диалог всплыл случайно.
  • Сохраняйте состояние при повороте экрана. Переменные вроде selectedSize потеряются, если не поместить их в ViewModel.
  • Используйте Material Design. Современные приложения выглядят лучше с MaterialAlertDialogBuilder вместо обычного AlertDialog.

Итоги

Сегодня вы освоили диалоговые окна в рамках Android Studio Kotlin уроки. Мы разобрали AlertDialog с одной и двумя кнопками, списком, радио-кнопками и даже кастомной разметкой. Теперь вы можете дать пользователю возможность подтверждать действия или выбирать настройки, не загромождая основной интерфейс. Добавьте диалог в своё приложение — например, подтверждение выхода или выбор цвета темы — и закрепите навык на практике.