Добавить в корзинуПозвонить
Найти в Дзене

Разработка экрана редактирования профиля Jetpack Compose

Нам нужно реализовать логику переключения между режимом «Просмотр» и «Редактирование», добавить строгую валидацию полей и реализовать расчет возраста.
1. Подготовка модели данных
Для удобства создадим класс, который будет хранить данные профиля.
data class UserProfile(

Нам нужно реализовать логику переключения между режимом «Просмотр» и «Редактирование», добавить строгую валидацию полей и реализовать расчет возраста.

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 }

}

}