Tugas 5

 Nama : Heru Dwi Kurniawan

NRP : 5025211055

Kelas : PPB B


Tugas 5  Membuat Water Bottle App

Untuk proyek terbaru saya, saya sedang mencoba merakit aplikasi Android simpel yang bernama Water Bottle App menggunakan Android Studio. Aplikasi ini tidak hanya menghitung volume air di dalam botol, tetapi juga memiliki fungsi tambahan yang menarik. Misalnya, pengguna bisa memilih jenis botol yang berbeda-beda atau bahkan mengatur target harian untuk minum air. Dengan menekan tombol 'drink', aplikasi akan merekam setiap kali pengguna minum air dan menambahkan volume yang sesuai ke dalam botol virtual. Saya sangat bersemangat untuk melihat bagaimana proyek ini berkembang!

package com.example.hydrationtracker

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.fillMaxWidth
import androidx.compose.foundation.layout.height
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.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.foundation.layout.width

@Composable
fun HydrationBottle(
    modifier: Modifier = Modifier,
    totalCapacity: Int,
    measurementUnit: String,
    currentUsage: Int,
    waterColor: Color = Color(0xff50C4ED),
    containerColor: Color = Color.White,
    lidColor: Color = Color(0xFFFBA834)
) {

    val waterLevel = animateFloatAsState(
        targetValue = (currentUsage.toFloat() / totalCapacity.toFloat()),
        label = "Water Level Animation",
        animationSpec = tween(durationMillis = 1000)
    ).value

    val currentUsageAnim = animateIntAsState(
        targetValue = currentUsage,
        label = "Current Usage Animation",
        animationSpec = tween(durationMillis = 1000)
    ).value

    Box(
        modifier = modifier
            .width(200.dp)
            .height(600.dp)
    ) {

        Canvas(modifier = Modifier.fillMaxSize()) {
            val canvasWidth = size.width
            val canvasHeight = size.height

            val lidWidth = size.width * 0.55f
            val lidHeight = size.height * 0.13f

            // Draw the bottle structure
            val bottlePath = Path().apply {
                moveTo(canvasWidth * 0.3f, canvasHeight * 0.1f)
                lineTo(canvasWidth * 0.3f, canvasHeight * 0.2f)
                quadraticBezierTo(
                    0f, canvasHeight * 0.3f, // Control point
                    0f, canvasHeight * 0.4f
                )
                lineTo(0f, canvasHeight * 0.95f)
                quadraticBezierTo(
                    0f, canvasHeight,
                    canvasWidth * 0.05f, canvasHeight
                )

                lineTo(canvasWidth * 0.95f, canvasHeight)
                quadraticBezierTo(
                    canvasWidth, canvasHeight,
                    canvasWidth, canvasHeight * 0.95f
                )
                lineTo(canvasWidth, canvasHeight * 0.4f)
                quadraticBezierTo(
                    canvasWidth, canvasHeight * 0.3f,
                    canvasWidth * 0.7f, canvasHeight * 0.2f
                )
                lineTo(canvasWidth * 0.7f, canvasHeight * 0.2f)
                lineTo(canvasWidth * 0.7f, canvasHeight * 0.1f)

                close()
            }
            clipPath(
                path = bottlePath
            ) {
                // Fill the bottle
                drawRect(
                    color = containerColor,
                    size = size,
                    topLeft = Offset(0f, 0f)
                )

                // Draw the water level
                val waterLevelY = (1 - waterLevel) * size.height

                val waterPath = Path().apply {
                    moveTo(
                        x = 0f,
                        y = waterLevelY
                    )
                    lineTo(
                        x = size.width,
                        y = waterLevelY
                    )
                    lineTo(
                        x = size.width,
                        y = size.height
                    )
                    lineTo(
                        x = 0f,
                        y = size.height
                    )
                    close()
                }
                drawPath(
                    path = waterPath,
                    color = waterColor,
                )
            }

            // Draw the bottle lid
            drawRoundRect(
                color = lidColor,
                size = Size(lidWidth, lidHeight),
                topLeft = Offset(size.width / 2 - lidWidth / 2f, 0f),
                cornerRadius = CornerRadius(45f, 45f)
            )
        }
        val displayText = buildAnnotatedString {
            withStyle(
                style = SpanStyle(
                    color = if (waterLevel > 0.5f) containerColor else waterColor,
                    fontSize = 44.sp
                )
            ) {
                append(currentUsageAnim.toString())
            }
            withStyle(
                style = SpanStyle(
                    color = if (waterLevel > 0.5f) containerColor else waterColor,
                    fontSize = 22.sp
                )
            ) {
                append(" ")
                append(measurementUnit)
            }
        }

        Box(
            modifier = Modifier
                .fillMaxSize()
                .fillMaxHeight(),
            contentAlignment = Alignment.Center
        ) {
            Text(text = displayText)
        }
    }
}

@Preview
@Composable
fun HydrationBottlePreview() {
    HydrationBottle(
        totalCapacity = 2000,
        measurementUnit = "ml",
        currentUsage = 120
    )
}








Komentar

Postingan populer dari blog ini

Tugas Apsi 1 ( APSI E )

Tugas 1 - PBB B

Tugas 2