Compare commits

..

No commits in common. "92e1a93aa5e1ceed15946cc730d6c551e7b62a3d" and "076428c67eb33d47864b8130b02d090ac646f991" have entirely different histories.

33 changed files with 445 additions and 280 deletions

View File

@ -1,10 +1,24 @@
Kalkulator BMI Tip Time - Solution Code
=============== =================================
Silahkan kembangkan aplikasi ini untuk melakukan perhitungan BMI Solution code for the [Android Basics with Compose](https://developer.android.com/courses/android-basics-compose/course): Tip Time app.
Petunjuk lebih detil dapat dibaca di
https://docs.google.com/document/d/1iGiC0Bg3Bdcd2Maq45TYkCDUkZ5Ql51E/edit?rtpof=true
Starter dimodifikasi dan terinspirasi dari: Introduction
https://developer.android.com/codelabs/basic-android-compose-calculate-tip#0 ------------
The Tip Time app contains various UI elements for calculating a tip,
teaching about user input, and State in Compose.
Pre-requisites
--------------
* Experience with Kotlin syntax.
* How to create and run a project in Android Studio.
Getting Started
---------------
1. Install Android Studio, if you don't already have it.
2. Download the sample.
3. Import the sample into Android Studio.
4. Build and run the sample.

View File

@ -17,7 +17,6 @@
plugins { plugins {
id("com.android.application") id("com.android.application")
id("org.jetbrains.kotlin.android") id("org.jetbrains.kotlin.android")
id("org.jetbrains.kotlin.plugin.compose")
} }
android { android {
@ -46,15 +45,18 @@ android {
} }
} }
compileOptions { compileOptions {
sourceCompatibility = JavaVersion.VERSION_17 sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_17 targetCompatibility = JavaVersion.VERSION_1_8
} }
kotlinOptions { kotlinOptions {
jvmTarget = JavaVersion.VERSION_17.toString() jvmTarget = "1.8"
} }
buildFeatures { buildFeatures {
compose = true compose = true
} }
composeOptions {
kotlinCompilerExtensionVersion = rootProject.extra["compose_compiler_version"].toString()
}
packaging { packaging {
resources { resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}" excludes += "/META-INF/{AL2.0,LGPL2.1}"
@ -65,7 +67,7 @@ android {
dependencies { dependencies {
implementation(platform("androidx.compose:compose-bom:2024.12.01")) implementation(platform("androidx.compose:compose-bom:2024.11.00"))
implementation("androidx.activity:activity-compose:1.9.3") implementation("androidx.activity:activity-compose:1.9.3")
implementation("androidx.compose.material3:material3") implementation("androidx.compose.material3:material3")
implementation("androidx.compose.ui:ui") implementation("androidx.compose.ui:ui")
@ -76,7 +78,7 @@ dependencies {
testImplementation("junit:junit:4.13.2") testImplementation("junit:junit:4.13.2")
androidTestImplementation(platform("androidx.compose:compose-bom:2024.12.01")) androidTestImplementation(platform("androidx.compose:compose-bom:2024.11.00"))
androidTestImplementation("androidx.compose.ui:ui-test-junit4") androidTestImplementation("androidx.compose.ui:ui-test-junit4")
androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1") androidTestImplementation("androidx.test.espresso:espresso-core:3.6.1")
androidTestImplementation("androidx.test.ext:junit:1.2.1") androidTestImplementation("androidx.test.ext:junit:1.2.1")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 284 KiB

View File

@ -1,219 +1,196 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.tiptime package com.example.tiptime
import android.os.Bundle import android.os.Bundle
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.compose.foundation.Image import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.background import androidx.annotation.DrawableRes
import androidx.compose.foundation.layout.* import androidx.annotation.StringRes
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.layout.Arrangement
import androidx.compose.material3.* import androidx.compose.foundation.layout.Column
import androidx.compose.runtime.* 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.padding
import androidx.compose.foundation.layout.safeDrawingPadding
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Switch
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.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.example.tiptime.ui.theme.TipTimeTheme import com.example.tiptime.ui.theme.TipTimeTheme
import java.text.NumberFormat
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge()
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContent { setContent {
TipTimeTheme { TipTimeTheme {
Surface(modifier = Modifier.fillMaxSize(), color = Color(0xFFF4F4F4)) {
BMICalculatorApp()
}
}
}
}
}
@Composable
fun BMICalculatorApp() {
var showSplash by remember { mutableStateOf(true) }
if (showSplash) {
SplashScreen(onStartClick = { showSplash = false })
} else {
BMIScreen()
}
}
@Composable
fun SplashScreen(onStartClick: () -> Unit) {
Box(
modifier = Modifier
.fillMaxSize()
.background(Color(0xFF2196F3)),
contentAlignment = Alignment.Center
) {
Column(horizontalAlignment = Alignment.CenterHorizontally) {
// kalau logomu putih, ubah background jadi putih biar kelihatan
Surface( Surface(
color = Color.White, modifier = Modifier.fillMaxSize(),
shape = RoundedCornerShape(100.dp),
modifier = Modifier.size(150.dp)
) { ) {
Image( TipTimeLayout()
painter = painterResource(id = R.drawable.logo),
contentDescription = "Logo",
modifier = Modifier
.fillMaxSize()
.padding(20.dp)
)
} }
Spacer(modifier = Modifier.height(16.dp))
Text(
text = "BMI Checker",
fontSize = 34.sp,
color = Color.White,
fontWeight = FontWeight.Bold
)
Spacer(modifier = Modifier.height(24.dp))
Button(
onClick = onStartClick,
colors = ButtonDefaults.buttonColors(containerColor = Color.White),
shape = RoundedCornerShape(12.dp)
) {
Text("Get Started", color = Color(0xFF2196F3), fontSize = 18.sp)
} }
} }
} }
} }
@Composable @Composable
fun BMIScreen() { fun TipTimeLayout() {
var height by remember { mutableStateOf("") } var amountInput by remember { mutableStateOf("") }
var weight by remember { mutableStateOf("") } var tipInput by remember { mutableStateOf("") }
var bmi by remember { mutableStateOf<Double?>(null) } var roundUp by remember { mutableStateOf(false) }
var selectedUnit by remember { mutableStateOf("Metric") }
val unitOptions = listOf("Metric (kg/cm)", "US (lbs/inch)") val amount = amountInput.toDoubleOrNull() ?: 0.0
val tipPercent = tipInput.toDoubleOrNull() ?: 0.0
val tip = calculateTip(amount, tipPercent, roundUp)
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxSize() .statusBarsPadding()
.padding(20.dp), .padding(horizontal = 40.dp)
horizontalAlignment = Alignment.CenterHorizontally .verticalScroll(rememberScrollState())
.safeDrawingPadding(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) { ) {
Text( Text(
text = "BMI Calculator", text = stringResource(R.string.calculate_tip),
fontSize = 30.sp,
fontWeight = FontWeight.Bold,
color = Color(0xFF2196F3)
)
Spacer(Modifier.height(24.dp))
// Pilihan Metric / US
Row(
horizontalArrangement = Arrangement.Center,
modifier = Modifier.fillMaxWidth()
) {
unitOptions.forEach { option ->
val isSelected = selectedUnit == option
Button(
onClick = { selectedUnit = option },
colors = ButtonDefaults.buttonColors(
containerColor = if (isSelected) Color(0xFF2196F3) else Color.LightGray
),
shape = RoundedCornerShape(50.dp),
modifier = Modifier modifier = Modifier
.padding(horizontal = 6.dp) .padding(bottom = 16.dp, top = 40.dp)
.height(45.dp) .align(alignment = Alignment.Start)
) { )
EditNumberField(
label = R.string.bill_amount,
leadingIcon = R.drawable.money,
keyboardOptions = KeyboardOptions.Default.copy(
keyboardType = KeyboardType.Number,
imeAction = ImeAction.Next
),
value = amountInput,
onValueChanged = { amountInput = it },
modifier = Modifier.padding(bottom = 32.dp).fillMaxWidth(),
)
EditNumberField(
label = R.string.how_was_the_service,
leadingIcon = R.drawable.percent,
keyboardOptions = KeyboardOptions.Default.copy(
keyboardType = KeyboardType.Number,
imeAction = ImeAction.Done
),
value = tipInput,
onValueChanged = { tipInput = it },
modifier = Modifier.padding(bottom = 32.dp).fillMaxWidth(),
)
RoundTheTipRow(
roundUp = roundUp,
onRoundUpChanged = { roundUp = it },
modifier = Modifier.padding(bottom = 32.dp)
)
Text( Text(
option, text = stringResource(R.string.tip_amount, tip),
color = if (isSelected) Color.White else Color.Black, style = MaterialTheme.typography.displaySmall
fontSize = 13.sp
) )
} Spacer(modifier = Modifier.height(150.dp))
}
}
Spacer(Modifier.height(24.dp))
OutlinedTextField(
value = height,
onValueChange = { if (it.all { c -> c.isDigit() || c == '.' }) height = it },
label = { Text("Tinggi Badan (${if (selectedUnit.startsWith("Metric")) "cm" else "inch"})") },
modifier = Modifier.fillMaxWidth()
)
Spacer(Modifier.height(12.dp))
OutlinedTextField(
value = weight,
onValueChange = { if (it.all { c -> c.isDigit() || c == '.' }) weight = it },
label = { Text("Berat Badan (${if (selectedUnit.startsWith("Metric")) "kg" else "lbs"})") },
modifier = Modifier.fillMaxWidth()
)
Spacer(Modifier.height(20.dp))
Button(
onClick = {
val h = height.toDoubleOrNull()
val w = weight.toDoubleOrNull()
if (h != null && w != null && h > 0) {
bmi = if (selectedUnit.startsWith("Metric")) {
w / ((h / 100) * (h / 100))
} else {
703 * (w / (h * h))
}
}
},
modifier = Modifier.fillMaxWidth(),
colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF2196F3))
) {
Text("Hitung BMI", fontSize = 18.sp, color = Color.White)
}
Spacer(Modifier.height(30.dp))
bmi?.let {
HasilBMI(bmi = it)
}
} }
} }
@Composable @Composable
fun HasilBMI(bmi: Double) { fun EditNumberField(
val (category, imageRes) = when { @StringRes label: Int,
bmi < 18.5 -> "Underweight" to R.drawable.stickman_kurus @DrawableRes leadingIcon: Int,
bmi < 25 -> "Normal" to R.drawable.stickman_normal keyboardOptions: KeyboardOptions,
bmi < 30 -> "Overweight" to R.drawable.stickman_overweight value: String,
else -> "Obesity" to R.drawable.stickman_obesitas onValueChanged: (String) -> Unit,
} modifier: Modifier = Modifier
) {
TextField(
value = value,
singleLine = true,
leadingIcon = { Icon(painter = painterResource(id = leadingIcon), null) },
modifier = modifier,
onValueChange = onValueChanged,
label = { Text(stringResource(label)) },
keyboardOptions = keyboardOptions
)
}
Column(horizontalAlignment = Alignment.CenterHorizontally) { @Composable
Text( fun RoundTheTipRow(
text = String.format("BMI Anda: %.1f", bmi), roundUp: Boolean,
fontSize = 22.sp, onRoundUpChanged: (Boolean) -> Unit,
fontWeight = FontWeight.Medium, modifier: Modifier = Modifier
textAlign = TextAlign.Center ) {
) Row(
Text( modifier = modifier.fillMaxWidth(),
text = "Kategori: $category", verticalAlignment = Alignment.CenterVertically
fontSize = 20.sp, ) {
color = Color.Gray, Text(text = stringResource(R.string.round_up_tip))
textAlign = TextAlign.Center Switch(
)
Spacer(Modifier.height(16.dp))
Image(
painter = painterResource(id = imageRes),
contentDescription = category,
modifier = Modifier modifier = Modifier
.fillMaxWidth(0.7f) .fillMaxWidth()
.aspectRatio(1f) .wrapContentWidth(Alignment.End),
checked = roundUp,
onCheckedChange = onRoundUpChanged
) )
} }
} }
/**
* Calculates the tip based on the user input and format the tip amount
* according to the local currency.
* Example would be "$10.00".
*/
private fun calculateTip(amount: Double, tipPercent: Double = 15.0, roundUp: Boolean): String {
var tip = tipPercent / 100 * amount
if (roundUp) {
tip = kotlin.math.ceil(tip)
}
return NumberFormat.getCurrencyInstance().format(tip)
}
@Preview(showBackground = true)
@Composable
fun TipTimeLayoutPreview() {
TipTimeTheme {
TipTimeLayout()
}
}

View File

@ -1,74 +1,185 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<vector <!--
android:height="108dp" ~ Copyright (C) 2023 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ https://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp" android:width="108dp"
android:viewportHeight="108" android:height="108dp"
android:viewportWidth="108" android:viewportWidth="108"
xmlns:android="http://schemas.android.com/apk/res/android"> android:viewportHeight="108">
<path android:fillColor="#3DDC84" <path
android:pathData="M0,0h108v108h-108z"/> android:fillColor="#3DDC84"
<path android:fillColor="#00000000" android:pathData="M9,0L9,108" android:pathData="M0,0h108v108h-108z" />
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> <path
<path android:fillColor="#00000000" android:pathData="M19,0L19,108" android:fillColor="#00000000"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:pathData="M9,0L9,108"
<path android:fillColor="#00000000" android:pathData="M29,0L29,108" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:strokeColor="#33FFFFFF" />
<path android:fillColor="#00000000" android:pathData="M39,0L39,108" <path
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:fillColor="#00000000"
<path android:fillColor="#00000000" android:pathData="M49,0L49,108" android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:strokeWidth="0.8"
<path android:fillColor="#00000000" android:pathData="M59,0L59,108" android:strokeColor="#33FFFFFF" />
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> <path
<path android:fillColor="#00000000" android:pathData="M69,0L69,108" android:fillColor="#00000000"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:pathData="M29,0L29,108"
<path android:fillColor="#00000000" android:pathData="M79,0L79,108" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:strokeColor="#33FFFFFF" />
<path android:fillColor="#00000000" android:pathData="M89,0L89,108" <path
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:fillColor="#00000000"
<path android:fillColor="#00000000" android:pathData="M99,0L99,108" android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:strokeWidth="0.8"
<path android:fillColor="#00000000" android:pathData="M0,9L108,9" android:strokeColor="#33FFFFFF" />
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> <path
<path android:fillColor="#00000000" android:pathData="M0,19L108,19" android:fillColor="#00000000"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:pathData="M49,0L49,108"
<path android:fillColor="#00000000" android:pathData="M0,29L108,29" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:strokeColor="#33FFFFFF" />
<path android:fillColor="#00000000" android:pathData="M0,39L108,39" <path
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:fillColor="#00000000"
<path android:fillColor="#00000000" android:pathData="M0,49L108,49" android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:strokeWidth="0.8"
<path android:fillColor="#00000000" android:pathData="M0,59L108,59" android:strokeColor="#33FFFFFF" />
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> <path
<path android:fillColor="#00000000" android:pathData="M0,69L108,69" android:fillColor="#00000000"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:pathData="M69,0L69,108"
<path android:fillColor="#00000000" android:pathData="M0,79L108,79" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:strokeColor="#33FFFFFF" />
<path android:fillColor="#00000000" android:pathData="M0,89L108,89" <path
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:fillColor="#00000000"
<path android:fillColor="#00000000" android:pathData="M0,99L108,99" android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:strokeWidth="0.8"
<path android:fillColor="#00000000" android:pathData="M19,29L89,29" android:strokeColor="#33FFFFFF" />
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> <path
<path android:fillColor="#00000000" android:pathData="M19,39L89,39" android:fillColor="#00000000"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:pathData="M89,0L89,108"
<path android:fillColor="#00000000" android:pathData="M19,49L89,49" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:strokeColor="#33FFFFFF" />
<path android:fillColor="#00000000" android:pathData="M19,59L89,59" <path
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:fillColor="#00000000"
<path android:fillColor="#00000000" android:pathData="M19,69L89,69" android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:strokeWidth="0.8"
<path android:fillColor="#00000000" android:pathData="M19,79L89,79" android:strokeColor="#33FFFFFF" />
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> <path
<path android:fillColor="#00000000" android:pathData="M29,19L29,89" android:fillColor="#00000000"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:pathData="M0,9L108,9"
<path android:fillColor="#00000000" android:pathData="M39,19L39,89" android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:strokeColor="#33FFFFFF" />
<path android:fillColor="#00000000" android:pathData="M49,19L49,89" <path
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:fillColor="#00000000"
<path android:fillColor="#00000000" android:pathData="M59,19L59,89" android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:strokeWidth="0.8"
<path android:fillColor="#00000000" android:pathData="M69,19L69,89" android:strokeColor="#33FFFFFF" />
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> <path
<path android:fillColor="#00000000" android:pathData="M79,19L79,89" android:fillColor="#00000000"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector> </vector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 574 KiB

View File

@ -0,0 +1,23 @@
<!--
~ Copyright (C) 2023 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ https://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M7.5,11C9.43,11 11,9.43 11,7.5S9.43,4 7.5,4S4,5.57 4,7.5S5.57,11 7.5,11zM7.5,6C8.33,6 9,6.67 9,7.5S8.33,9 7.5,9S6,8.33 6,7.5S6.67,6 7.5,6z"/>
<path android:fillColor="@android:color/white" android:pathData="M4.0025,18.5831l14.5875,-14.5875l1.4142,1.4142l-14.5875,14.5875z"/>
<path android:fillColor="@android:color/white" android:pathData="M16.5,13c-1.93,0 -3.5,1.57 -3.5,3.5s1.57,3.5 3.5,3.5s3.5,-1.57 3.5,-3.5S18.43,13 16.5,13zM16.5,18c-0.83,0 -1.5,-0.67 -1.5,-1.5s0.67,-1.5 1.5,-1.5s1.5,0.67 1.5,1.5S17.33,18 16.5,18z"/>
</vector>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 484 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 731 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 758 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 713 KiB

View File

@ -1,5 +1,22 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2023 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ https://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/> <background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@mipmap/ic_launcher_foreground"/> <foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon> </adaptive-icon>

View File

@ -1,5 +1,22 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2023 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ https://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/> <background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@mipmap/ic_launcher_foreground"/> <foreground android:drawable="@drawable/ic_launcher_foreground" />
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon> </adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@ -15,11 +15,10 @@
~ limitations under the License. ~ limitations under the License.
--> -->
<resources> <resources>
<string name="app_name">BMI Calculator</string> <string name="app_name">Tip Time</string>
<string name="calculate_tip">Calculate BMI</string> <string name="calculate_tip">Calculate Tip</string>
<string name="height">Tinggi Badan</string> <string name="bill_amount">Bill Amount</string>
<string name="weight">Berat Badan</string> <string name="how_was_the_service">Tip Percentage</string>
<string name="use_usc">Gunakan Unit USC (lbs/in)?</string> <string name="round_up_tip">Round up tip?</string>
<string name="bmi_calculation">BMI Anda: %s</string> <string name="tip_amount">Tip Amount: %s</string>
<string name="bmi_category">Kategori: %s</string>
</resources> </resources>

View File

@ -14,10 +14,14 @@
* limitations under the License. * limitations under the License.
*/ */
buildscript {
extra.apply {
set("compose_compiler_version", "1.5.3")
}
}
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins { plugins {
id("com.android.application") version "8.13.0" apply false id("com.android.application") version "8.7.3" apply false
id("com.android.library") version "8.13.0" apply false id("com.android.library") version "8.7.3" apply false
id("org.jetbrains.kotlin.android") version "2.1.0" apply false id("org.jetbrains.kotlin.android") version "1.9.10" apply false
id("org.jetbrains.kotlin.plugin.compose") version "2.1.0" apply false
} }

View File

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

3
gradlew vendored
View File

@ -86,7 +86,8 @@ done
# shellcheck disable=SC2034 # shellcheck disable=SC2034
APP_BASE_NAME=${0##*/} APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum MAX_FD=maximum