Membuat Login Form Elegan dengan Jetpack Compose di Android Studio
Nama : Iftala Zahri Sukmana
NRP : 5025221002
Kelas : G
Kode GitHub : https://github.com/ifzahri/ppb/tree/main/loginform
Selamat datang di blog teknis hari ini! Dalam artikel ini, saya akan membahas cara membuat form login yang modern dan fungsional menggunakan Jetpack Compose, library UI terbaru untuk pengembangan aplikasi Android. Mari kita pelajari cara membuat form login dengan field email, password, tombol login, dan opsi "Lupa Password" yang profesional.
Pendahuluan
Jetpack Compose telah mengubah cara kita membangun antarmuka pengguna di Android. Dengan pendekatan deklaratif dan reaktif, Compose memungkinkan pengembang untuk membuat UI yang kompleks dengan kode yang lebih sedikit dan lebih mudah dipahami.
Dalam tutorial ini, kita akan fokus pada pembuatan komponen login yang sering menjadi pintu gerbang utama untuk aplikasi. Kita akan mengimplementasikan:
- Field input untuk email dengan validasi
- Field input untuk password dengan visualisasi khusus
- Tombol login dengan fungsi validasi
- Tautan "Lupa Password" yang interaktif
Prasyarat
Sebelum memulai, pastikan Anda memiliki:
- Android Studio versi terbaru (Arctic Fox atau yang lebih baru)
- Proyek Android dengan Jetpack Compose yang sudah dikonfigurasi
- Pengetahuan dasar tentang Kotlin dan Jetpack Compose
Langkah 1: Membuat Composable Login Screen
Mari kita mulai dengan membuat composable utama untuk form login. Buat file Kotlin baru dengan nama LoginScreen.kt dan tambahkan kode berikut:
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.unit.dp
@Composable
fun LoginScreen(
onLoginClick: (email: String, password: String) -> Unit,
onForgotPasswordClick: () -> Unit
) {
var email by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") }
var isEmailError by remember { mutableStateOf(false) }
var isPasswordError by remember { mutableStateOf(false) }
Column(
modifier = Modifier
.fillMaxSize()
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(
text = "Selamat Datang Kembali",
style = MaterialTheme.typography.headlineMedium
)
Spacer(modifier = Modifier.height(32.dp))
// Field Email
OutlinedTextField(
value = email,
onValueChange = {
email = it
isEmailError = false
},
label = { Text("Email") },
isError = isEmailError,
modifier = Modifier.fillMaxWidth(),
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Email,
imeAction = ImeAction.Next
),
singleLine = true
)
if (isEmailError) {
Text(
text = "Masukkan alamat email yang valid",
color = MaterialTheme.colorScheme.error,
style = MaterialTheme.typography.bodySmall,
modifier = Modifier.align(Alignment.Start)
)
}
Spacer(modifier = Modifier.height(16.dp))
// Field Password
OutlinedTextField(
value = password,
onValueChange = {
password = it
isPasswordError = false
},
label = { Text("Password") },
isError = isPasswordError,
visualTransformation = PasswordVisualTransformation(),
modifier = Modifier.fillMaxWidth(),
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Password,
imeAction = ImeAction.Done
),
singleLine = true
)
if (isPasswordError) {
Text(
text = "Password tidak boleh kosong",
color = MaterialTheme.colorScheme.error,
style = MaterialTheme.typography.bodySmall,
modifier = Modifier.align(Alignment.Start)
)
}
Spacer(modifier = Modifier.height(8.dp))
// Lupa Password
TextButton(
onClick = onForgotPasswordClick,
modifier = Modifier.align(Alignment.End)
) {
Text("Lupa Password?")
}
Spacer(modifier = Modifier.height(24.dp))
// Tombol Login
Button(
onClick = {
// Validasi sederhana
isEmailError = !isValidEmail(email)
isPasswordError = password.isEmpty()
if (!isEmailError && !isPasswordError) {
onLoginClick(email, password)
}
},
modifier = Modifier
.fillMaxWidth()
.height(50.dp)
) {
Text("Masuk")
}
}
}
// Validasi email sederhana
private fun isValidEmail(email: String): Boolean {
return android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches() && email.isNotEmpty()
}
Langkah 2: Mengintegrasikan dengan MainActivity
Setelah membuat composable login, kita perlu mengintegrasikan dengan MainActivity atau navigasi aplikasi kita. Berikut contoh bagaimana menggunakan LoginScreen di MainActivity:
package com.example.loginapp
import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.ui.Modifier
import com.example.loginapp.ui.theme.LoginAppTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
LoginAppTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
LoginScreen(
onLoginClick = { email, password ->
// Implementasi logika login di sini
performLogin(email, password)
},
onForgotPasswordClick = {
// Implementasi alur lupa password
navigateToForgotPassword()
}
)
}
}
}
}
private fun performLogin(email: String, password: String) {
// Pada aplikasi nyata, Anda akan mengautentikasi dengan backend
// Untuk demo, kita hanya menampilkan toast
Toast.makeText(
this,
"Mencoba login dengan: $email",
Toast.LENGTH_SHORT
).show()
// Biasanya Anda akan:
// 1. Memanggil API autentikasi
// 2. Menangani kasus sukses/gagal
// 3. Navigasi ke layar utama jika sukses
}
private fun navigateToForgotPassword() {
// Implementasi navigasi ke layar lupa password
Toast.makeText(
this,
"Menuju ke layar Lupa Password",
Toast.LENGTH_SHORT
).show()
}
}
Penjelasan Komponen Utama
Mari kita bahas beberapa elemen kunci dari implementasi kita:
1. State Management
var email by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") }
var isEmailError by remember { mutableStateOf(false) }
var isPasswordError by remember { mutableStateOf(false) }
Di Jetpack Compose, kita menggunakan remember dan mutableStateOf untuk mengelola state UI. Setiap perubahan pada state ini akan memicu rekomposisi UI.
2. Field Input dengan Validasi
OutlinedTextField(
value = email,
onValueChange = {
email = it
isEmailError = false
},
label = { Text("Email") },
isError = isEmailError,
// ...
)
if (isEmailError) {
Text(
text = "Masukkan alamat email yang valid",
color = MaterialTheme.colorScheme.error,
// ...
)
}
Kita menggunakan OutlinedTextField untuk input, dengan state isError yang menentukan apakah field dalam keadaan error. Pesan error ditampilkan hanya jika validasi gagal.
3. Visualisasi Password
visualTransformation = PasswordVisualTransformation()
Baris ini mengubah tampilan teks menjadi bintang (*) untuk menyembunyikan password, fitur keamanan standar pada form login.
4. Validasi Form
onClick = {
// Validasi sederhana
isEmailError = !isValidEmail(email)
isPasswordError = password.isEmpty()
if (!isEmailError && !isPasswordError) {
onLoginClick(email, password)
}
}
Kita melakukan validasi saat tombol login ditekan. Jika validasi berhasil, callback onLoginClick dipanggil dengan data email dan password.
5. Fungsi Validasi Email
private fun isValidEmail(email: String): Boolean {
return android.util.Patterns.EMAIL_ADDRESS.matcher(email).matches() && email.isNotEmpty()
}
Fungsi ini menggunakan pola regex bawaan Android untuk memverifikasi format email.
Styling dan UI/UX
Jetpack Compose menggunakan Material Design 3 secara default, yang memberikan tampilan yang modern dan konsisten. Layout kita memusatkan elemen-elemen di layar dan memberikan spacing yang tepat untuk keterbacaan.
Beberapa pertimbangan UI/UX:
- Text field menggunakan jenis keyboard yang sesuai (email dan password)
- Pesan error yang jelas dan informatif
- Tombol "Lupa Password" yang mudah diakses
- Tombol login yang lebar dan jelas
- Validasi realtime yang memberikan feedback langsung
Implementasi Backend (Lanjutan)
Dalam aplikasi nyata, Anda perlu menghubungkan form login dengan backend Anda. Berikut contoh skeleton untuk fungsi performLogin:
private fun performLogin(email: String, password: String) {
// Tampilkan loading indicator
setLoading(true)
viewModel.login(email, password)
.observe(this) { result ->
setLoading(false)
when (result) {
is Result.Success -> {
// Simpan token dan navigasi ke home screen
saveAuthToken(result.data.token)
navigateToHome()
}
is Result.Error -> {
// Tampilkan pesan error
showErrorMessage(result.message)
}
}
}
}
Kesimpulan
Dalam tutorial ini, kita telah membuat form login yang fungsional dan estetis menggunakan Jetpack Compose. Form ini mencakup semua elemen standar: input email dan password, validasi, tombol login, dan opsi lupa password.
Jetpack Compose memungkinkan kita membuat UI yang responsif dan interaktif dengan lebih sedikit kode dibandingkan pendekatan tradisional berbasis XML. Ini juga memfasilitasi penerapan praktik-praktik terbaik dalam desain UI/UX modern.
Komentar
Posting Komentar