Wednesday, April 24, 2024

Tugas 7 - Membuat Aplikasi Water Bottle

Nama     : Florentino Benedictus

NRP       : 5025201222

Tahun    : 2024

Kelas      : Pemrograman Perangkat Bergerak I

Link Implementasi      :  MainActivity.kt & WaterBottle.kt


Tugas 7 - Membuat Aplikasi Water Bottle

Pada tugas ini, dibuat aplikasi water bottle yaitu aplikasi botol air dengan animasi sehingga isinya dapat bertambah ketika user menekan tombol "Drink", pembuatan tugas menggunakan referensi Draw an Animated Water Bottle:

1. Inisiasi Proyek
Pertama-tama buka aplikasi Android Studio lalu pilih New Project -> Empty Activity. Kemudian ubah nama activity menjadi "WaterBottle" dan menggunakan level API minimum 24, lalu pilih Finish. Lalu tunggu beberapa saat sampai Android Studio selesai loading proyek. Untuk kemudahan maka digunakan virtual device Pixel 7 Pro yang telah dibuat sebelumnya.

2. Ubah Template Default
Pertama-tama, hapus fungsi Greeting pada template. Kemudian ubah isi setContent sehingga hanya berisi WaterBottleTheme.

3. Buat File WaterBottle.kt
Selanjutnya, buat file WaterBottle.kt. File ini akan berfungsi untuk menyimpan fungsi utama dari botol yang akan dibuat.

4. Buat Fungsi WaterBottle
Selanjutnya isi WaterBottle.kt dengan fungsi WaterBottle. Fungsi akan berisi modifier meliputi warna dan variabel dari botol yang akan dibuat. Kemudian buat juga composable Box yang akan digunakan untuk membuat botol.

5. Buat Canvas Pada WaterBottle
Selanjutnya, buat composable Canvas yang akan berisi garis maupun lengkungan yang akan menyusun botol yang dibuat menggunakan moveTo untuk menentukan posisi x dan y awal, lineTo untuk membuat garis lurus dari posisi saat ini ke titik (x,y), dan quadraticBezierTo untuk membuat kurva dari posisi saat ini ke (x2, y2) dengan control point (x1, x2).


6. Panggil Fungsi WaterBottle Pada MainActivity.kt
Selanjutnya kembali ke MainActivity.kt untuk memanggil fungsi WaterBottle yang telah dibuat. Karena nantinya isi dari botol akan bertambah, maka digunakan variabel usedWaterAmount sebagai indikator jumlah air dalam botol saat ini dan totalWaterAmount sebagai ukuran maksimal botol. Kemudian tambahkan button yang berfungsi untuk menambah jumlah air pada botol.

7. Tambahkan clipPath() Pada WaterBottle.kt
Gunakan clipPath() yang akan menggunakan bottleBodyPath yang telah dibuat, kemudian drawRect() akan digunakan untuk menggambar frame botol. Lalu run ulang App, maka terlihat pada tampilan kerangka botol telah berhasil dibuat.

8. Buat Air Pada WaterBottle.kt
Selanjutnya tambahkan value yang menyimpan persentase air dalam botol yaitu waterPercentage. Kemudian gambarkan air di dalam botol pada clipPath() dengan cara yang sama seperti pembuatan botol yaitu drawPath().
Berikut adalah tampilan setelah air berhasil ditambahkan pada botol. Dengan menggunakan tombol yang telah dibuat sebelumnya pada MainActivity.kt, jumlah air pada botol dapat ditambahkan.

9. Tambahkan Tutup Botol
Selanjutnya, buat tampilan tutup botol dengan drawRoundRect menggunakan width dan height yang diinginkan, sehingga hasil akan terlihat seperti gambar di atas.

10. Menampilkan Jumlah Air Dalam Botol
Selanjutnya, gunakan usedWaterAmountAnimation untuk melakukan tracking terhadap jumlah ml yang terisi pada botol. Lalu tambahkan composable box yang akan menyimpan teks jumlah air saat ini pada tengah layar.
Tambahkan pengecekan corner case pada button sehingga isi botol tidak melebihi totalWaterAmount.


11. Hasil Implementasi
Berikut adalah tampilan ketika button Drink dipencet, maka jumlah ml dan isi air dalam botol akan bertambah dan terdapat animasi sehingga tidak terkesan kaku.



Berikut adalah isi code MainActivity.kt & WaterBottle.kt:
MainActivity.kt
package com.example.waterbottle
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.waterbottle.ui.theme.WaterBottleTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
WaterBottleTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
var usedWaterAmount by remember {
mutableIntStateOf(100)
}
val totalWaterAmount = remember {
2500
}
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
WaterBottle(
totalWaterAmount = totalWaterAmount,
unit = "ml",
usedWaterAmount = usedWaterAmount,
)
Spacer(modifier = Modifier.height(20.dp))
Text(
text = "Total Amount is : $totalWaterAmount",
textAlign = TextAlign.Center
)
Button(
onClick = { if (usedWaterAmount < totalWaterAmount) usedWaterAmount += 200 },
colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF279EFF))
) {
Text(text = "Drink")
}
}
}
}
}
}
}
view raw MainActivity.kt hosted with ❤ by GitHub

WaterBottle.kt
package com.example.waterbottle
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.animateIntAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.drawscope.clipPath
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@Composable
fun WaterBottle(
modifier: Modifier = Modifier,
totalWaterAmount: Int,
unit: String,
usedWaterAmount: Int,
waterWavesColor: Color = Color(0xFF279EFF),
bottleColor: Color = Color.LightGray,
capColor: Color = Color(0xFF0065B9)
) {
val waterPercentage = animateFloatAsState(
targetValue = (usedWaterAmount.toFloat() / totalWaterAmount.toFloat()),
label = "Water Waves animation",
animationSpec = tween(durationMillis = 1000)
).value
val usedWaterAmountAnimation = animateIntAsState(
targetValue = usedWaterAmount,
label = "Used water amount animation",
animationSpec = tween(durationMillis = 1000)
).value
Box(modifier = modifier
.width(200.dp)
.height(600.dp)
) {
Canvas(modifier = Modifier.fillMaxSize()) {
val width = size.width
val height = size.height
val capWidth = size.width * 0.55f
val capHeight = size.height * 0.13f
val bottleBodyPath = Path().apply {
moveTo(
x = width * 0.3f, y = height * 0.1f
)
lineTo(
x = width * 0.3f, y = height * 0.2f
)
quadraticBezierTo(
x1 = 0f, y1 = height * 0.3f,
x2 = 0f, y2 = height * 0.4f
)
lineTo(
x = 0f, y = height * 0.95f
)
quadraticBezierTo(
x1 = 0f, y1 = height,
x2 = width * 0.05f, y2 = height
)
lineTo(
x = width * 0.95f, y = height
)
quadraticBezierTo(
x1 = width, y1 = height,
x2 = width, y2 = height * 0.95f
)
lineTo(
x = width, y = height * 0.4f
)
quadraticBezierTo(
x1 = width, y1 = height * 0.3f,
x2 = width * 0.7f, y2 = height * 0.2f
)
lineTo(
x = width * 0.7f, y = height * 0.1f
)
close()
}
clipPath(
path = bottleBodyPath
) {
// Draw the color of the bottle
drawRect(
color = bottleColor,
size = size,
topLeft = Offset(0f, 0f)
)
val waterWavesYPosition = (1 - waterPercentage) * size.height
val wavesPath = Path().apply {
moveTo(
x = 0f,
y = waterWavesYPosition
)
lineTo(
x = size.width,
y = waterWavesYPosition
)
lineTo(
x = size.width,
y = size.height
)
lineTo(
x = 0f,
y = size.height
)
close()
}
drawPath(
path = wavesPath,
color = waterWavesColor,
)
}
drawRoundRect(
color = capColor,
size = Size(capWidth, capHeight),
topLeft = Offset(size.width / 2 - capWidth / 2f, 0f),
cornerRadius = CornerRadius(45f, 45f)
)
}
val text = buildAnnotatedString {
withStyle(
style = SpanStyle(
color = if (waterPercentage > 0.5f) bottleColor else waterWavesColor,
fontSize = 44.sp
)
) {
append(usedWaterAmountAnimation.toString())
}
withStyle(
style = SpanStyle(
color = if (waterPercentage > 0.5f) bottleColor else waterWavesColor,
fontSize = 22.sp
)
) {
append(" ")
append(unit)
}
}
Box(
modifier = Modifier
.fillMaxSize()
.fillMaxHeight(),
contentAlignment = Alignment.Center
) {
Text(text = text)
}
}
}
view raw WaterBottle.kt hosted with ❤ by GitHub


Referensi

https://kuliahppb.blogspot.com/2024/04/material-design.html
https://www.youtube.com/watch?v=vmT0SScA2lA

Wednesday, April 17, 2024

Tugas 6 - Membuat Kalkulator Sederhana

Nama     : Florentino Benedictus

NRP       : 5025201222

Tahun    : 2024

Kelas      : Pemrograman Perangkat Bergerak I

Link Implementasi      :  Link Github


Tugas 6 - Membuat Kalkulator Sederhana

Pada tugas ini, dibuat aplikasi kalkulator yang memungkinkan penjumlahan, pengurangan, perkalian, dan pembagian dua angka yang ditentukan oleh user. Aplikasi kalkulator akan memanfaatkan composable state untuk membuat variabel yang persisten dan melakukan perubahan nilai variabel. Implementasi menggunakan referensi Basic Calculator App:

1. Inisiasi Proyek
Pertama-tama buka aplikasi Android Studio lalu pilih New Project -> Empty Activity. Kemudian ubah nama activity menjadi "MyCalculator" dan menggunakan level API minimum 24, lalu pilih Finish. Lalu tunggu beberapa saat sampai Android Studio selesai loading proyek. Untuk kemudahan maka digunakan virtual device Pixel 7 Pro yang telah dibuat sebelumnya.

2. Ubah Template Default
Pertama-tama, hapus fungsi Greeting pada template. Kemudian ubah isi setContent sehingga memanggil CalculatorScreen(). CalculatorScreen() merupakan fungsi utama yang akan dibuat selanjutnya.

3. Buat Fungsi CalculatorScreen()
Pada fungsi CalculatorScreen(), buat variabel num1 dan num2 yang akan digunakan sebagai placeholder angka untuk operasi aritmatika. Kemudian tambahkan TextField pada composable Column sehingga dapat ditampilkan di layar.

4. Tambahkan Context
Karena akan digunakan Toast message untuk menampilkan hasil operasi aritmatika, maka perlu ditentukan context yang digunakan yaitu LocalContext.current.

5. Tambahkan Button Operasi Aritmatika
Selanjutnya, buat composable Row yang akan berisi 4 button dengan teks Add, Sub, Mul, dan Div yang masing-masing akan berfungsi untuk melakukan operasi penjumlahan, pengurangan, perkalian, dan pembagian dari kedua input angka. Ketika tiap button diklik, maka hasil operasi aritmatika dari kedua angka input akan disimpan pada variabel result kemudian ditampilkan menggunakan pesan Toast.

6. Cek Hasil Implementasi
Run ulang app sehingga program terload ulang, maka tampilan kalkulator yang telah dibuat akan terlihat pada device yang dipilih. Berikut adalah contoh hasil untuk masing-masing operasi aritmatika:

A. Penjumlahan
B. Pengurangan
C. Perkalian
D. Pembagian

Berikut adalah isi code MainActivity.kt:
MainActivity.kt
package com.example.mycalculator
import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.mycalculator.ui.theme.MyCalculatorTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
CalculatorScreen()
}
}
}
@Composable
fun CalculatorScreen() {
var num1 by remember {
mutableStateOf("0")
}
var num2 by remember {
mutableStateOf("0")
}
val context = LocalContext.current
Column {
TextField(value = num1, onValueChange = {
num1 = it
})
TextField(value = num2, onValueChange = {
num2 = it
})
Row {
Button(onClick = {
var result = num1.toInt() + num2.toInt()
Toast.makeText(context, "Result of $num1 + $num2 is $result", Toast.LENGTH_SHORT).show()
}) {
Text(text = "Add")
}
Spacer(modifier = Modifier.width(16.dp))
Button(onClick = {
var result = num1.toInt() - num2.toInt()
Toast.makeText(context, "Result of $num1 - $num2 is $result", Toast.LENGTH_SHORT).show()
}) {
Text(text = "Sub")
}
Spacer(modifier = Modifier.width(16.dp))
Button(onClick = {
var result = num1.toInt() * num2.toInt()
Toast.makeText(context, "Result of $num1 * $num2 is $result", Toast.LENGTH_SHORT).show()
}) {
Text(text = "Mul")
}
Spacer(modifier = Modifier.width(16.dp))
Button(onClick = {
var result = num1.toInt() / num2.toInt()
Toast.makeText(context, "Result of $num1 / $num2 is $result", Toast.LENGTH_SHORT).show()
}) {
Text(text = "Div")
}
}
}
}
view raw MainActivity.kt hosted with ❤ by GitHub

Wednesday, April 3, 2024

Tugas 5 - Membuat Halaman Log In

 Nama     : Florentino Benedictus

NRP       : 5025201222

Tahun    : 2024

Kelas      : Pemrograman Perangkat Bergerak I

Link Implementasi      :  Link Github Tugas 5


Tugas 5 - Membuat Halaman Log In

Pada tugas ini, dibuat halaman log in menggunakan composable image, textfield, dan button yang berfungsi sebagai tampilan antarmuka awal dari suatu aplikasi. Tampilan antarmuka tersebut memungkinkan pengembang software untuk kemudian menambahkan implementasi database dan logika backend. Implementasi menggunakan referensi dari Studi Kasus Membuat Halaman Login:

1. Inisiasi Proyek
Pertama-tama buka aplikasi Android Studio lalu pilih New Project -> Empty Activity. Kemudian ubah nama activity menjadi "MyLogin" dan menggunakan level API minimum 26 sesuai tutorial, lalu pilih Finish. Lalu tunggu beberapa saat sampai Android Studio selesai loading proyek. Untuk kemudahan maka digunakan virtual device Pixel 7 Pro yang telah dibuat sebelumnya.

2. Ubah Template Default
Hapus composable Greeting preview default yang terbuat ketika project diinisiasi, kemudian hapus juga isi setContent dari onCreate dan ganti dengan LoginScreen(). LoginScreen() merupakan fungsi utama yang akan dibuat selanjutnya.

3. Import Resource
Kemudian, import resource image icon yang diperlukan melalui View -> Tool Windows -> Resource Manager.
Jika sudah ter-import maka akan terlihat resource-resource gambar tersebut akan tersedia pada app/res/drawable.

4. Buat LoginScreen.kt
Selanjutnya, akan dibuat LoginScreen.kt pada app/java/com.example.mylogin yang akan berisi LoginScreen() yaitu fungsi composable utama yang akan dipanggil pada MainActivity.kt. Pada LoginScreen() akan ditampilkan image icon login, teks "Welcome Back", dan teks "Login to your account" dalam composable column. Sesuaikan spacing menggunakan spacer dan posisikan juga menggunakan alignment center sehingga posisi composable column tersebut terletak di tengah layar. Kemudian run aplikasi menggunakan device yang diinginkan, maka tampilannya akan terlihat seperti pada gambar.

5. Tambahkan Textfield
Selanjutnya, tambahkan textfield untuk input email dan password user menggunakan composable OutlinedTextField. Kemudian tambahkan juga spacer sesuai keperluan.

6. Tambahkan Button Login dan Forgot Password
Tambahkan button Login di bawah textfield menggunakan composable button, Forgot Password menggunakan composable text dengan modifier clickable sehingga dapat ditekan, dan tambahkan teks bagian bawah untuk login menggunakan third-party app tertentu.

7. Tambahkan Image Third-Party App
Image-image seperti Facebook, Github, dan Twitter dapat dimasukkan pada program menggunakan composable Image. Kemudian, agar gambar-gambar tersebut dapat diklik maka composable image dapat diberi modifier clickable seperti teks forgot password pada poin sebelumnya. Lokasi dapat dirapikan dengan cara memasukkan image-image tersebut pada composable Row. Hasil akhir dapat terlihat seperti gambar di atas.

8. Cek Hasil & Modifikasi
Selanjutnya, untuk memastikan bahwa tombol sudah berfungsi dengan benar maka dapat digunakan variabel email dan password yang akan menyimpan input user.
Tambahkan pada onValueChange untuk textfield email dan password sehingga variabel email dan password akan terupdate ketika user memasukkan input teks. Tambahkan juga PasswordVisualTransformation() sehingga password tidak terlihat secara plaintext.
Selanjutnya, tambahkan logging info sehingga ketika user mencoba login maupun klik forgot password, logging akan terlihat di console
Tambahkan juga logging info ketika user klik tombol untuk login melalui Facebook, Github, dan Twitter.
Untuk mengecek log, klik View -> Tool Windows -> Logcat. Maka pada bagian bawah terminal untuk output logging akan terlihat
Kemudian run ulang app, dan masukkan beberapa value pada textfield email dan password maupun klik forgot password dan third-party apps. Maka terlihat bahwa tombol-tombol tersebut sudah fungsional.

Berikut adalah isi code MainActivity.kt dan LoginScreen.kt:
MainActivity.kt
package com.example.mylogin
import android.os.Bundle
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.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.example.mylogin.ui.theme.MyLoginTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
LoginScreen()
}
}
}
view raw MainActivity.kt hosted with ❤ by GitHub

LoginScreen.kt
package com.example.mylogin
import android.util.Log
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun LoginScreen(){
var email by remember {
mutableStateOf("")
}
var password by remember {
mutableStateOf("")
}
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Image(painter = painterResource(
id = R.drawable.icon_login),
contentDescription = "Login image",
modifier = Modifier.size(200.dp))
Text(
text = "Welcome Back",
fontSize = 28.sp,
fontWeight = FontWeight.Bold
)
Spacer(modifier = Modifier.height(4.dp))
Text(text = "Login to your account")
Spacer(modifier = Modifier.height(4.dp))
OutlinedTextField(
value = email,
onValueChange = { email = it },
label = {
Text(text = "Email address")
}
)
Spacer(modifier = Modifier.height(16.dp))
OutlinedTextField(
value = password,
onValueChange = { password = it },
label = {
Text(text = "Password")
},
visualTransformation = PasswordVisualTransformation()
)
Spacer(modifier = Modifier.height(16.dp))
Button(onClick = { Log.i("LoginPassword", "Email: $email | Password: $password") }) {
Text(text = "Login")
}
Spacer(modifier = Modifier.height(32.dp))
Text(
text = "Forgot password?",
modifier = Modifier.clickable {
Log.i("ForgotPassword", "Forgot password clicked")
}
)
Spacer(modifier = Modifier.height(32.dp))
Text(text = "Or sign in with")
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceEvenly
) {
Image(
painter = painterResource(id = R.drawable.icon_facebook),
contentDescription = "Facebook Login",
modifier = Modifier
.size(60.dp)
.clickable {
// Facebook clicked
Log.i("LoginFacebook", "Using Facebook login")
}
)
Image(
painter = painterResource(id = R.drawable.icon_github),
contentDescription = "Github Login",
modifier = Modifier
.size(60.dp)
.clickable {
// Github clicked
Log.i("LoginGithub", "Using Github login")
}
)
Image(
painter = painterResource(id = R.drawable.icon_twitter),
contentDescription = "Twitter Login",
modifier = Modifier
.size(60.dp)
.clickable {
// Twitter clicked
Log.i("LoginTwitter", "Using Twitter login")
}
)
}
}
}
view raw LoginScreen.kt hosted with ❤ by GitHub

EAS PPB I - Aplikasi Alfamind

Nama       : Florentino Benedictus NRP          : 5025201222 Tahun     : 2024 Kelas        : Pemrograman Perangkat Bergerak I Link Desain An...