Tugas 5 - Pemrograman Perangkat Bergerak


Nama : James Silaban

NRP : 5025201169

kelas : PBB F

Pembuatan Halaman Login

1. Membuat File Baru

    Pada penugasan kali ini, akan dibutuhkan 3 tambahan file:
    - LoginTextField.kt --> untuk menyimpan template dari Input Field
    - HeaderText.kt --> mengatur tampilan header
    - LoginScreen.kt --> mengatur tampilan UI Login keseluruhan
   
    Berikut struktur penyimpanan folder aplikasi

myloginpbb\
|--- ui\
|    |--- components\
|    |    |--- LoginTextField.kt
|    |--- login\
|         |--- HeaderText.kt
|         |--- LoginScreen.kt 
|--- MainActicity.kt

2. Membuat Template Input Field

    Pada file LoginTextField.kt, akan dibuat template untuk input field pada tampilan login dengan menggunakan komponen OutlinedTextField(). File ini akan di import pada file LoginScreen.kt    

LoginTextField.kt
@Composable
fun LoginTextField(
    value: String,
    onValueChange: (String) -> Unit,
    labelText: String,
    leadingIcon: ImageVector? = null,
    keyboardType: KeyboardType = KeyboardType.Text,
    visualTransformation: VisualTransformation = VisualTransformation.None,
    modifier: Modifier = Modifier,
) {
    OutlinedTextField(
        value = value,
        onValueChange = onValueChange,
        label = { Text(labelText) },
        leadingIcon = { if( leadingIcon != null ) Icon(imageVector = leadingIcon, contentDescription = null) },
        keyboardOptions = KeyboardOptions( keyboardType = keyboardType ),
        visualTransformation = visualTransformation,
        shape = RoundedCornerShape(30),
        modifier = modifier
    )
}

3. Membuat Tampilan Header Text

    Tampilan header akan dibuat di file terpisah, dimana akan diatur ukuran serta tingkat ketebalan text. File ini akan dipanggil pada file LoginScreen.kt.

 HeaderText.kt
@Composable
fun HeaderText(
    text: String,
    modifier: Modifier = Modifier,
) {
    Text(
        text = text,
        style = MaterialTheme.typography.displayMedium,
        fontWeight = FontWeight.Bold,
        modifier = modifier
    )
}

4. Membuat Tampilan Login Screen

    Pada file LoginScreent.kt, akan terdapat 2 fungsi composable, yaitu LoginScreen() dan  AlternativeLoginOptions().

    Pada LoginScreen(), akan dipanggil fungsi HeaderText.kt sebagai tampilan header pada form. Kemudian, pada bagian input, akan dipanggil file LoginTextField.kt. Selain header dan input field, akan dibuat juga bagian button beserta opsi alternative login. Pengaturan tampilan opsi alternative login dilakukan pada fungsi AlternativeLoginOptions().

    Pada opsi alternative login, kita butuh import gambar sesuai dengan media sosial yang akan menjadi opsi alternative login. Setelah diimport, image tersebut dipanggil dan disimpan dalam sebuah variable List. Kemudian akan dilakukan perulangan pada variable list dengan menggunakan .forEachIndexed() untuk menampilkan setiap icon gambar.

LoginScreen.kt
@Composable
fun LoginScreen() {
    val (userName, setUserName) = rememberSaveable {
        mutableStateOf("")
    }
    val (password, setPassword) = rememberSaveable {
        mutableStateOf("")
    }
    val (checked, setChecked) = rememberSaveable {
        mutableStateOf(false)
    }
    val context = LocalContext.current

    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(defaultPadding),
        verticalArrangement = Arrangement.Top,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        HeaderText(
            text = "Login",
            modifier = Modifier
                .padding(vertical = defaultPadding)
                .align(Alignment.Start),
        )
        LoginTextField(
            value = userName,
            onValueChange = setUserName,
            labelText = "Username",
            leadingIcon = Icons.Default.Person,
            modifier = Modifier.fillMaxWidth()
        )
        Spacer(modifier = Modifier.height(itemSpacing))
        LoginTextField(
            value = password,
            onValueChange = setPassword,
            labelText = "Password",
            leadingIcon = Icons.Default.Lock,
            keyboardType = KeyboardType.Password,
            visualTransformation = PasswordVisualTransformation(),
            modifier = Modifier.fillMaxWidth()
        )
        Spacer(modifier = Modifier.height(itemSpacing))
        Row(
            horizontalArrangement = Arrangement.SpaceBetween,
            verticalAlignment = Alignment.CenterVertically,
            modifier = Modifier.fillMaxWidth()
        ) {
            Row(
                horizontalArrangement = Arrangement.Center,
                verticalAlignment = Alignment.CenterVertically
            ) {
                Checkbox(checked = checked, onCheckedChange = setChecked)
                Text(text = "Remember Me")
            }
            TextButton(onClick = { /*TODO*/ }) {
                Text(text = "Forgot Password?")
            }
        }
        Spacer(modifier = Modifier.height(itemSpacing))
        Button(
            onClick = { /*TODO*/ },
            modifier = Modifier.fillMaxWidth()
        ) {
            Text(text = "Login")
        }
        AlternativeLoginOptions(
            onIconClick = { index ->
                          when(index) {
                              0 -> {
                                  Toast.makeText(context, "Instagram Login Click", Toast.LENGTH_SHORT).show()
                              }
                              1 -> {
                                  Toast.makeText(context, "Github Login Click", Toast.LENGTH_SHORT).show()
                              }
                              2 -> {
                                  Toast.makeText(context, "Google Login Click", Toast.LENGTH_SHORT).show()
                              }
                          }
            },
            onSignUpClick = { /*TODO*/ },
            modifier = Modifier
                .fillMaxSize()
                .wrapContentSize(align = Alignment.BottomCenter)
        )
    }
}

@Composable
fun AlternativeLoginOptions(
    onIconClick: ( index: Int ) -> Unit,
    onSignUpClick: () -> Unit,
    modifier: Modifier = Modifier
) {
    val iconList = listOf(
        R.drawable.icon_instagram,
        R.drawable.icon_github,
        R.drawable.icon_google
    )
    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center,
        modifier = modifier.fillMaxWidth()
    ) {
        Text(text = "Or Sign In With")
        Row(
            horizontalArrangement = Arrangement.SpaceEvenly
        ) {
            iconList.forEachIndexed{ index, iconResId ->
                Spacer(modifier = Modifier.width(itemSpacing))
                Icon(
                    painter = painterResource(iconResId),
                    contentDescription = "Alternative Login",
                    modifier = Modifier
                        .size(32.dp)
                        .clickable {
                            onIconClick(index)
                        }
                        .clip(CircleShape)
                )
                Spacer(modifier = Modifier.width(itemSpacing))
            }
        }
        Spacer(modifier = Modifier.height(itemSpacing))
        Row(
            verticalAlignment = Alignment.CenterVertically
        ) {
            Text(text = "Don't have an Account?")
            TextButton(onClick = { /*TODO*/ }) {
                Text(text = "Sign Up")
            }
        }
    }
}

Berikut adalah tampilan akhir dari Halaman Login



Kode pada Penugasan 5 dapat dilihat pada link github berikut.


Referensi: https://www.youtube.com/watch?v=OlO58LDfN14&ab_channel=HoodLab 

Comments

Popular posts from this blog