What You Will Build
A polished login/signup page with email and password fields, a password visibility toggle, form validation, and a switch between login and registration modes. This is the authentication screen pattern used in virtually every app that requires user accounts.
Why Login Screens Are the First Real Compose Test
A login page exercises text input handling, visual transformations, keyboard options, conditional UI, and button enable/disable logic. If you can build a solid login screen, you have the foundation for any form-based interface in Compose.
Key Compose Concepts
- PasswordVisualTransformation for hiding password characters.
- KeyboardOptions(keyboardType = KeyboardType.Email) for email-optimized keyboard.
- Conditional button enabling with the
enabledparameter.
State Setup
var email by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") }
var passwordVisible by remember { mutableStateOf(false) }
var isLogin by remember { mutableStateOf(true) }
The Password Field with Visibility Toggle
OutlinedTextField(
value = password,
onValueChange = { password = it },
modifier = Modifier.fillMaxWidth(),
label = { Text("Password") },
leadingIcon = { Icon(Icons.Default.Lock, null) },
trailingIcon = {
IconButton(onClick = { passwordVisible = !passwordVisible }) {
Icon(
if (passwordVisible) Icons.Default.Visibility
else Icons.Default.VisibilityOff,
contentDescription = null
)
}
},
singleLine = true,
visualTransformation = if (passwordVisible)
VisualTransformation.None
else PasswordVisualTransformation()
)
Login Button with Validation
Button(
onClick = { /* Handle authentication */ },
modifier = Modifier
.fillMaxWidth()
.height(50.dp),
enabled = email.isNotBlank() && password.length >= 6
) {
Text(
if (isLogin) "Sign In" else "Sign Up",
fontSize = 16.sp
)
}
Spacer(Modifier.height(16.dp))
TextButton(onClick = { isLogin = !isLogin }) {
Text(
if (isLogin) "Don't have an account? Sign Up"
else "Already have an account? Sign In"
)
}
Tips and Pitfalls
- Minimum password length of 6 is enforced with
password.length >= 6in the enabled check, giving real-time feedback. - VisualTransformation.None vs PasswordVisualTransformation() toggles between showing and hiding the password. The toggle icon also updates to indicate the current state.
- Add verticalScroll to the Column modifier to prevent the soft keyboard from obscuring form fields on small screens.
- KeyboardType.Email shows the @ symbol prominently on the keyboard, reducing friction for email entry.
Minimum SDK: API 24+ with Compose BOM 2024.01+