Нам нужно реализовать логику переключения между режимом «Просмотр» и «Редактирование», добавить строгую валидацию полей и реализовать расчет возраста.
1. Подготовка модели данных
Для удобства создадим класс, который будет хранить данные профиля.
data class UserProfile(
val firstName: String = "Emmanuel",
val lastName: String = "Oyiboke",
val email: String = "primer@gmail.com",
val address: String = "Nigeria",
val birthDate: String = "28.03.2003"
)
2. Реализация экрана Profile (Просмотр)
@Composable
fun ProfileScreen(user: UserProfile, onEditClick: () -> Unit) {
Column(modifier = Modifier.fillMaxSize().padding(16.dp)) {
// Шапка с кнопкой редактирования
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
Text("Профиль", style = MaterialTheme.typography.headlineMedium)
IconButton(onClick = onEditClick) {
Icon(Icons.Default.Edit, contentDescription = "Edit", tint = Color(0xFF4DB6E1))
}
}
// Фото и автоматическая подпись
Image(painter = painterResource(id = R.drawable.avatar), contentDescription = null, ...)
Text(text = "${user.firstName} ${user.lastName}", style = MaterialTheme.typography.titleLarge)
// Поля (только чтение)
ProfileField(label = "Имя", value = user.firstName)
ProfileField(label = "Фамилия", value = user.lastName)
// ... и остальные поля
}
}
3. Реализация экрана Edit Profile (Редактирование)
Здесь сосредоточена вся логика ограничений из вашего ТЗ.
Логика валидации:
1. Email: it.length >= 12 && it.contains("@").
2. Текстовые поля (Имя, Фамилия, Адрес): it.length >= 20
3. Дата рождения:
Формат: дд.мм.гггг.
Возраст: от 14 до 99 лет.
Код функции валидации даты:
fun isValidAge(dateStr: String): Boolean {
return try {
val formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy")
val birthDate = LocalDate.parse(dateStr, formatter)
val age = Period.between(birthDate, LocalDate.now()).years
age in 14..99
} catch (e: Exception) {
false
}
}
Визуальная индикация:
Для каждого поля в OutlinedTextField используем параметр trailingIcon.
@Composable
fun EditField(
value: String,
label: String,
isValid: Boolean,
onValueChange: (String) -> Unit
) {
OutlinedTextField(
value = value,
onValueChange = onValueChange,
label = { Text(label) },
trailingIcon = {
if (value.isNotEmpty()) {
val icon = if (isValid) Icons.Default.Check else Icons.Default.Close
val color = if (isValid) Color.Blue else Color.Red
Icon(icon, contentDescription = null, tint = color)
}
},
modifier = Modifier.fillMaxWidth()
)
}
4. Сборка экрана редактирования
@Composable
fun EditProfileScreen(
currentProfile: UserProfile,
onSave: (UserProfile) -> Unit,
onBack: () -> Unit
) {
var firstName by remember { mutableStateOf(currentProfile.firstName) }
var email by remember { mutableStateOf(currentProfile.email) }
// ... остальные состояния
Column {
Row(verticalAlignment = Alignment.CenterVertically) {
IconButton(onClick = onBack) { Icon(Icons.Default.ArrowBack, "Back") }
Button(
onClick = { onSave(UserProfile(firstName, ...)) },
enabled = allFieldsValid() // Кнопка активна только если всё корректно
) {
Text("Сохранить")
}
}
// Поля ввода с проверкой
EditField("Имя", firstName, isValid = firstName.length >= 20) { firstName = it }
EditField("Email", email, isValid = email.length >= 12 && email.contains("@")) { email = it }
// Поле даты с проверкой возраста
EditField("Дата рождения", bDay, isValid = isValidAge(bDay)) { bDay = it }
}
}