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

Разработка экранов регистрации и авторизации Jetpack Compose

Чтобы подсистема работала, нам нужно не просто нарисовать кнопочки, а связать их логикой навигации и валидации.
Я разделю процесс на 3 четких этапа: создание структуры, настройка регистрации и настройка входа.
Этап 1: Подготовка фундамента (Навигация)
Чтобы передать данные из SignUp в LoginIn, нам нужен NavController. В Jetpack Compose это делается через NavHost. Мы определим два маршрута.

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

Я разделю процесс на 3 четких этапа: создание структуры, настройка регистрации и настройка входа.

Этап 1: Подготовка фундамента (Навигация)

Чтобы передать данные из SignUp в LoginIn, нам нужен NavController. В Jetpack Compose это делается через NavHost. Мы определим два маршрута.

  1. signup: экран регистрации.
  2. login/{email}/{password}: экран входа, который «ждет» на вход почту и пароль.

val navController = rememberNavController()

NavHost(navController = navController, startDestination = "signup") {

composable("signup") {

SignUpScreen(navController)

}

composable(

route = "login/{email}/{password}",

arguments = listOf(

navArgument("email") { defaultValue = "" },

navArgument("password") { defaultValue = "" }

)

) { backStackEntry ->

val email = backStackEntry.arguments?.getString("email")

val pass = backStackEntry.arguments?.getString("password")

LoginInScreen(navController, email, pass)

}

}

Этап 2: Создание SignUp.kt

1. Переменные состояния (State)

Для каждого поля создаем mutableStateOf. Это «память» экрана.

var login by remember { mutableStateOf("") }

var email by remember { mutableStateOf("") }

var password by remember { mutableStateOf("") }

var confirmPassword by remember { mutableStateOf("") }

var isChecked by remember { mutableStateOf(false) }

// Переменные для хранения текстов ошибок

var loginError by remember { mutableStateOf<String?>(null) }

var emailError by remember { mutableStateOf<String?>(null) }

var passError by remember { mutableStateOf<String?>(null) }

2. Применяем ограничения

Теперь «научим» кнопку проверять условия из задания:

  1. Логин: login.length >= 8
  2. Email: email.length >= 12 && email.contains("@")
  3. Пароль: KeyboardOptions(keyboardType = KeyboardType.Number) и длина >= 8.
  4. Совпадение: password == confirmPassword.

Пример:

Button(

onClick = {

// Сбрасываем ошибки перед проверкой

loginError = if (login.length < 8) "Минимум 8 символов" else null

emailError = if (email.length < 12 || !email.contains("@")) "Минимум 12 знаков и @" else null

passError = if (password.length < 8) "Минимум 8 цифр" else if (password != confirmPassword) "Пароли не совпадают" else null

// Если всё чисто и чекбокс нажат — летим на экран логина

if (loginError == null && emailError == null && passError == null && isChecked) {

navController.navigate("login/$email/$password")

}

},

// Кнопка визуально блокируется, если поля пусты или чекбокс не нажат

enabled = login.isNotEmpty() && email.isNotEmpty() && isChecked

) {

Text("Зарегистрироваться")

}

Этап 3: Создание LoginIn.kt

Здесь мы реализуем требования по отображению пароля и автоподстановке.

1. Автоматическая вставка

Мы принимаем initialEmail и initialPass из навигации и сразу кладем их в state.

@Composable

fun LoginInScreen(navController: NavController, initialEmail: String?, initialPass: String?) {

var email by remember { mutableStateOf(initialEmail ?: "") }

var password by remember { mutableStateOf(initialPass ?: "") }

// Переменная для переключения "глазика"

var isPasswordVisible by remember { mutableStateOf(false) }

2. Реализация отображения пароля

Используем параметр visualTransformation в OutlinedTextField.

OutlinedTextField(

value = password,

onValueChange = { password = it },

label = { Text("Пароль") },

// Если true — текст виден, если false — заменяется точками

visualTransformation = if (isPasswordVisible) VisualTransformation.None else PasswordVisualTransformation(),

trailingIcon = {

IconButton(onClick = { isPasswordVisible = !isPasswordVisible }) {

val icon = if (isPasswordVisible) Icons.Default.Visibility else Icons.Default.VisibilityOff

Icon(imageVector = icon, contentDescription = null)

}

}

)

3. Ограничения экрана Login

Тут проверка проще, но она обязательна.

Button(

onClick = {

if (email.isEmpty() || password.isEmpty()) {

// Показываем Toast или текст ошибки: "Все поля обязательны"

} else if (!email.contains("@")) {

// Ошибка: "Email должен содержать @"

} else {

// Успешный вход

}

}

) {

Text("Войти")

}