Найти в Дзене

Разработка диалогового окна Jetpack Compose

Для реализации этой задачи на Jetpack Compose, нам необходимо создать состояние, которое будет храниться на основном экране и передаваться в диалоговое окно. Это обеспечит сохранение выбора между вызовами.
1. Подготовка состояний на основном экране
Чтобы диалоговое окно «помнило» предыдущий выбор, мы объявим переменную selectedOption на уровне экрана.
// Возможные варианты выбора

Для реализации этой задачи на Jetpack Compose, нам необходимо создать состояние, которое будет храниться на основном экране и передаваться в диалоговое окно. Это обеспечит сохранение выбора между вызовами.

1. Подготовка состояний на основном экране

Чтобы диалоговое окно «помнило» предыдущий выбор, мы объявим переменную selectedOption на уровне экрана.

// Возможные варианты выбора

val options = listOf("Yearly", "Monthly", "Weekly")

// Состояние на главном экране

var showDialog by remember { mutableStateOf(false) }

var savedChoice by remember { mutableStateOf("") } // Текст для отображения на экране

var lastSelectedOption by remember { mutableStateOf<String?>(null) } // Для памяти диалога

2. Создание кастомного диалогового окна

@Composable

fun CustomChoiceDialog(

initialSelection: String?,

onDismiss: () -> Unit,

onConfirm: (String) -> Unit,

onCancel: () -> Unit

) {

// Внутреннее состояние окна для выбора (до нажатия кнопки Сохранить)

var currentSelection by remember { mutableStateOf(initialSelection) }

Dialog(onDismissRequest = onDismiss) {

Surface(

shape = RoundedCornerShape(28.dp),

color = Color.White,

modifier = Modifier.fillMaxWidth().padding(16.dp)

) {

Column(

modifier = Modifier.padding(24.dp),

horizontalAlignment = Alignment.CenterHorizontally

) {

Text("Выберите из списка", style = TextStyle(fontWeight = FontWeight.Bold, fontSize = 20.sp))

Spacer(modifier = Modifier.height(8.dp))

Text("Выберите формат отображения даты:", color = Color.Gray, fontSize = 14.sp)

Spacer(modifier = Modifier.height(20.dp))

// Список переключателей

options.forEach { option ->

val isSelected = currentSelection == option

Row(

modifier = Modifier

.fillMaxWidth()

.padding(vertical = 4.dp)

.border(1.dp, if (isSelected) Color(0xFFE3F2FD) else Color.LightGray, RoundedCornerShape(12.dp))

.background(if (isSelected) Color(0xFFE3F2FD) else Color.Transparent, RoundedCornerShape(12.dp))

.clickable { currentSelection = option }

.padding(12.dp),

verticalAlignment = Alignment.CenterVertically

) {

RadioButton(

selected = isSelected,

onClick = { currentSelection = option },

colors = RadioButtonDefaults.colors(selectedColor = Color(0xFF007BFF))

)

Text(text = option, style = TextStyle(fontWeight = FontWeight.Medium))

}

}

Spacer(modifier = Modifier.height(24.dp))

// Кнопки управления

Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(12.dp)) {

OutlinedButton(

onClick = onCancel,

modifier = Modifier.weight(1.dp),

shape = RoundedCornerShape(12.dp),

border = BorderStroke(1.dp, Color(0xFF007BFF))

) {

Text("Отмена", color = Color(0xFF007BFF))

}

Button(

onClick = { currentSelection?.let { onConfirm(it) } },

modifier = Modifier.weight(1.dp),

shape = RoundedCornerShape(12.dp),

colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF007BFF)),

enabled = currentSelection != null

) {

Text("Сохранить", color = Color.White)

}

}

}

}

}

}

3. Логика работы

Первое открытие: Поскольку lastSelectedOption изначально равен null, ни один переключатель не будет выбран при первом запуске.

Кнопка «Сохранить»:

1. Обновляет savedChoice (текст отобразится на экране под именем "Lucas Scott").

2. Обновляет lastSelectedOption (чтобы диалог «запомнил» выбор для следующего раза).

3. Закрывает окно.

Кнопка «Отмена»:

1. Закрывает окно.

2. Вызывает Toast.makeText(context, "Ничего не выбрано", Toast.LENGTH_SHORT).show().

4. Внешний вид на экране

В центре экрана под текстом «Выбрал отображение даты:» мы просто выводим нашу переменную:

Text(

text = savedChoice,

style = TextStyle(fontWeight = FontWeight.Bold, fontSize = 24.sp),

modifier = Modifier.padding(top = 40.dp)

)