PPB I - Tugas 7 - Material Design - Membuat Aplikasi "Water Bottle" Sederhana

 Material Design - Membuat Aplikasi Water Bottle Sederhana

Link Github

    Pada pertemuan minggu ke-7 perkuliahan mata kuliah Pemrograman Perangkat Bergerak, kami membahas tentang Material Design sebagai guidline/panduan desain aplikasi perangkat lunak yang dibuat oleh Google. Sebagai tugas latihan, kami diminta membuat aplikasi Water Bottle sederhana. Aplikasi ini memungkinkan pengguna untuk melakukan interaksi minum (dengan mengeklik tombol Drink) dan total air yang diminum akan ditampilkan pada botol dengan animasi yang menarik. Pada aplikasi ini terdapat beberapa composable yang digunakan, seperti TextButton, dan Canvas.

    Langkah pertama adalah membuat proyek menggunakan activity kosong. Setelah membuat proyek, langkah selanjutnya adalah mengisi kolom Name dengan BottleWater, memilih level API minimum 26 (Oreo) di kolom Minimum SDK, dan kemudian mengklik tombol Finish. Selanjutnya, membuat file WaterBottle.kt untuk menuliskan kode composable terkait antarmuka dan fungsionalitas botol air seperti dibawah ini:

package com.ariefbadrussholeh.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.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,
waterColor: Color = Color(0xff279eff),
bottleColor: Color = Color.White,
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(
bottleBodyPath
) {
drawRect(
color = bottleColor,
size = size
)
val waterWavesYPosition = (1 - waterPercentage) * size.height
val waterPath = 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 = waterPath,
color = waterColor
)
}
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 waterColor,
fontSize = 44.sp
)
) {
append(usedWaterAmountAnimation.toString())
}
withStyle(
style = SpanStyle(
color = if (waterPercentage > 0.5f) bottleColor else waterColor,
fontSize = 22.sp
)
) {
append(" ")
append(unit)
}
}
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center){
Text(text = text)
}
}
}
view raw WaterBottle.kt hosted with ❤ by GitHub

    Komponen WaterBottle menerima beberapa parameter seperti totalWaterAmount (total air dalam botol), unit (satuan untuk total air), dan usedWaterAmount (jumlah air yang telah diminum). Selain itu, terdapat juga parameter opsional seperti waterColor (warna air), bottleColor (warna botol), dan capColor (warna penutup botol).

    Di dalam komponen, kita menggunakan Canvas untuk menggambar botol air. Terdapat juga animasi yang diatur menggunakan fungsi animateFloatAsState dan animateIntAsState untuk memberikan efek animasi pada tingkat air yang berubah. Path digunakan untuk menggambar bentuk botol air, sedangkan drawPath digunakan untuk menggambar air di dalam botol dengan warna sesuai dengan parameter waterColor.

    Selain itu, komponen juga menampilkan teks yang menunjukkan jumlah air yang diminum. Pengaturan warna teks dan animasi perubahan jumlah air juga diatur berdasarkan tingkat air yang ada dalam botol.

    Langkah berikutnya adalah memodifikasi file MainActivity.kt seperti dibawah ini:

package com.ariefbadrussholeh.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.foundation.layout.width
import androidx.compose.material3.Button
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
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.unit.dp
import com.ariefbadrussholeh.waterbottle.ui.theme.WaterBottleTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
WaterBottleTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = Color(0xFFECEFF1)
) {
var usedAmount by remember {
mutableIntStateOf(400)
}
val totalWaterAmount = remember {
2400
}
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
WaterBottle(
totalWaterAmount = totalWaterAmount,
unit = "ml",
usedWaterAmount = usedAmount,
modifier = Modifier.width(250.dp)
)
Spacer(modifier = Modifier.height(20.dp))
Text(text = "Total amount is : $totalWaterAmount ml")
Button(onClick = { usedAmount += 200 }) {
Text(text = "Drink")
}
}
}
}
}
}
}
view raw MainActivity.kt hosted with ❤ by GitHub

     Column menempatkan konten secara vertikal di tengah layar dengan menggunakan alignment dan arrangement dari Compose. Di dalam Column, terdapat komponen WaterBottle yang menampilkan botol air dengan jumlah air yang sudah diminum. Jumlah air yang sudah diminum dan total air dalam botol disediakan sebagai data yang diingat (remember) menggunakan mutableIntStateOf dan remember. Di bawah WaterBottle, terdapat Teks yang menampilkan total air dalam botol. Dan terakhir, terdapat Button yang ketika diklik, akan menambah jumlah air yang sudah diminum sebanyak 200 ml.

    Langkah Terakhir adalah menjalankan aplikasi. Berikut adalah tampilan aplikasi pada perangkat Android:

Arief Badrus Sholeh
5025201228
Pemrograman Perangkat Bergerak I
2023/2024

Komentar