Compare commits

...

11 Commits

Author SHA1 Message Date
SKILLISSUE1
2677e3f16c UTS 2025-11-06 23:39:10 +07:00
099c35f19a Update README.md 2025-11-06 12:04:44 +07:00
0ee43c2e9a First update calculation 2025-11-06 11:34:31 +07:00
7053fa6573 First update labels 2025-11-06 11:10:35 +07:00
51c9a8e5ff First commit 2025-11-06 09:58:07 +07:00
renovate[bot]
b029b3dd10
Update all dependencies 8.7.3 to v8.8.0 (#271)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-01-10 05:25:39 +00:00
renovate[bot]
90545a4a4d
Update dependency gradle 8.11.1 to v8.12 (#263)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-21 03:18:17 +00:00
renovate[bot]
e075e6ded8
Update dependency androidx.compose:compose-bom 2024.11.00 to v2024.12.01 (#260)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-12-12 03:31:35 +00:00
Tomáš Mlynarič
7db6c366a3 Update to kotlin 2.1.0 2024-12-09 17:16:15 +01:00
Jose Alcérreca
076428c67e
Merge pull request #257 from google-developer-training/mlykotom-renovate-fix
Add branches to renovate
2024-12-09 13:44:24 +00:00
Tomáš Mlynarič
59c134aec9
Add branches to renovate 2024-12-09 14:35:04 +01:00
34 changed files with 148 additions and 106 deletions

View File

@ -2,5 +2,10 @@
"$schema": "https://docs.renovatebot.com/renovate-schema.json", "$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [ "extends": [
"local>android/.github:renovate-config" "local>android/.github:renovate-config"
],
"baseBranches": [
"main",
"starter",
"state"
] ]
} }

View File

@ -1,24 +1,21 @@
Tip Time - Solution Code Kalkulator BMI
================================= ===============
Langkah-langkah:
Solution code for the [Android Basics with Compose](https://developer.android.com/courses/android-basics-compose/course): Tip Time app. 1. Clone Repository Project
Saya meng-clone repository project dari GitHub menggunakan Android Studio untuk dijadikan dasar pengerjaan tugas.
2. Modifikasi Tampilan Aplikasi
Saya meminta bantuan ChatGPT dan DeepSeek untuk memberikan saran tampilan aplikasi agar lebih menarik. Setelah itu, saya menyesuaikan tampilan sesuai arahan yang diberikan.
Introduction 3. Mengubah Icon Aplikasi (APK)
------------ Saya mengganti icon aplikasi melalui fitur Image Asset di Android Studio dengan icon baru sesuai arahan dari ChatGPT.
The Tip Time app contains various UI elements for calculating a tip,
teaching about user input, and State in Compose.
4. Review dan Uji Coba
Setelah perubahan selesai, saya menjalankan aplikasi untuk memastikan tampilan dan icon sudah berubah dengan baik.
Pre-requisites Petunjuk lebih detil dapat dibaca di
-------------- https://docs.google.com/document/d/1iGiC0Bg3Bdcd2Maq45TYkCDUkZ5Ql51E/edit?rtpof=true
* Experience with Kotlin syntax.
* How to create and run a project in Android Studio.
Starter dimodifikasi dan terinspirasi dari:
Getting Started https://developer.android.com/codelabs/basic-android-compose-calculate-tip#0
---------------
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,6 +17,7 @@
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 {
@ -45,18 +46,15 @@ android {
} }
} }
compileOptions { compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8 sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_17
} }
kotlinOptions { kotlinOptions {
jvmTarget = "1.8" jvmTarget = JavaVersion.VERSION_17.toString()
} }
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}"
@ -67,7 +65,7 @@ android {
dependencies { dependencies {
implementation(platform("androidx.compose:compose-bom:2024.11.00")) implementation(platform("androidx.compose:compose-bom:2024.12.01"))
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")
@ -78,7 +76,7 @@ dependencies {
testImplementation("junit:junit:4.13.2") testImplementation("junit:junit:4.13.2")
androidTestImplementation(platform("androidx.compose:compose-bom:2024.11.00")) androidTestImplementation(platform("androidx.compose:compose-bom:2024.12.01"))
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")

View File

@ -20,9 +20,9 @@
<application <application
android:allowBackup="true" android:allowBackup="true"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/app_icon"
android:label="@string/app_name" android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/app_icon_round"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.TipTime" android:theme="@style/Theme.TipTime"
tools:targetApi="33"> tools:targetApi="33">

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

View File

@ -54,8 +54,9 @@ import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.tooling.preview.Preview 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 import java.text.DecimalFormat
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@ -75,13 +76,16 @@ class MainActivity : ComponentActivity() {
@Composable @Composable
fun TipTimeLayout() { fun TipTimeLayout() {
var amountInput by remember { mutableStateOf("") } var heightInput by remember { mutableStateOf("") }
var tipInput by remember { mutableStateOf("") } var weightInput by remember { mutableStateOf("") }
var roundUp by remember { mutableStateOf(false) } var useUSC by remember { mutableStateOf(false) }
val amount = amountInput.toDoubleOrNull() ?: 0.0 val height = heightInput.toDoubleOrNull() ?: 0.0
val tipPercent = tipInput.toDoubleOrNull() ?: 0.0 val weight = weightInput.toDoubleOrNull() ?: 0.0
val tip = calculateTip(amount, tipPercent, roundUp)
val bmi = calculateBMI(height, weight, useUSC)
val category = calculateBMICategory(bmi)
val categoryColor = getCategoryColor(category)
Column( Column(
modifier = Modifier modifier = Modifier
@ -93,42 +97,61 @@ fun TipTimeLayout() {
verticalArrangement = Arrangement.Center verticalArrangement = Arrangement.Center
) { ) {
Text( Text(
text = stringResource(R.string.calculate_tip), text = "Calculate BMI",
style = MaterialTheme.typography.headlineMedium,
color = MaterialTheme.colorScheme.primary,
modifier = Modifier modifier = Modifier
.padding(bottom = 16.dp, top = 40.dp) .padding(bottom = 16.dp, top = 40.dp)
.align(alignment = Alignment.Start) .align(alignment = Alignment.Start)
) )
EditNumberField( EditNumberField(
label = R.string.bill_amount, label = R.string.height,
leadingIcon = R.drawable.money, leadingIcon = R.drawable.number,
keyboardOptions = KeyboardOptions.Default.copy( keyboardOptions = KeyboardOptions.Default.copy(
keyboardType = KeyboardType.Number, keyboardType = KeyboardType.Number,
imeAction = ImeAction.Next imeAction = ImeAction.Next
), ),
value = amountInput, value = heightInput,
onValueChanged = { amountInput = it }, onValueChanged = { heightInput = it },
modifier = Modifier.padding(bottom = 32.dp).fillMaxWidth(), modifier = Modifier
.padding(bottom = 32.dp)
.fillMaxWidth(),
) )
EditNumberField( EditNumberField(
label = R.string.how_was_the_service, label = R.string.weight,
leadingIcon = R.drawable.percent, leadingIcon = R.drawable.number,
keyboardOptions = KeyboardOptions.Default.copy( keyboardOptions = KeyboardOptions.Default.copy(
keyboardType = KeyboardType.Number, keyboardType = KeyboardType.Number,
imeAction = ImeAction.Done imeAction = ImeAction.Done
), ),
value = tipInput, value = weightInput,
onValueChanged = { tipInput = it }, onValueChanged = { weightInput = it },
modifier = Modifier.padding(bottom = 32.dp).fillMaxWidth(), modifier = Modifier
.padding(bottom = 32.dp)
.fillMaxWidth(),
) )
RoundTheTipRow(
roundUp = roundUp, RoundTheUnitRow(
onRoundUpChanged = { roundUp = it }, useUSC = useUSC,
onUnitChanged = { useUSC = it },
modifier = Modifier.padding(bottom = 32.dp) modifier = Modifier.padding(bottom = 32.dp)
) )
Text( Text(
text = stringResource(R.string.tip_amount, tip), text = "BMI Anda: $bmi",
style = MaterialTheme.typography.displaySmall style = MaterialTheme.typography.displaySmall,
color = MaterialTheme.colorScheme.onSurface
) )
Text(
text = "Kategori: $category",
fontSize = 20.sp,
color = categoryColor,
modifier = Modifier.padding(top = 8.dp)
)
Spacer(modifier = Modifier.height(150.dp)) Spacer(modifier = Modifier.height(150.dp))
} }
} }
@ -154,37 +177,73 @@ fun EditNumberField(
} }
@Composable @Composable
fun RoundTheTipRow( fun RoundTheUnitRow(
roundUp: Boolean, useUSC: Boolean,
onRoundUpChanged: (Boolean) -> Unit, onUnitChanged: (Boolean) -> Unit,
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
Row( Row(
modifier = modifier.fillMaxWidth(), modifier = modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
Text(text = stringResource(R.string.round_up_tip)) Text(
text = "Gunakan Unit (Metric/USC)",
color = MaterialTheme.colorScheme.onSurface
)
Switch( Switch(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.wrapContentWidth(Alignment.End), .wrapContentWidth(Alignment.End),
checked = roundUp, checked = useUSC,
onCheckedChange = onRoundUpChanged onCheckedChange = onUnitChanged
) )
} }
} }
/** /**
* Calculates the tip based on the user input and format the tip amount * Menghitung BMI berdasarkan rumus yang digunakan
* according to the local currency.
* Example would be "$10.00".
*/ */
private fun calculateTip(amount: Double, tipPercent: Double = 15.0, roundUp: Boolean): String { internal fun calculateBMI(height: Double, weight: Double, useUSC: Boolean): String {
var tip = tipPercent / 100 * amount if (height == 0.0 || weight == 0.0) return "0.0"
if (roundUp) {
tip = kotlin.math.ceil(tip) val bmi = if (useUSC) {
// Rumus USC: 703 * (berat (lbs) / (tinggi (in)^2))
703 * (weight / (height * height))
} else {
// Rumus Metric: berat (kg) / (tinggi (m)^2)
val heightInMeter = height / 100
weight / (heightInMeter * heightInMeter)
}
return DecimalFormat("#.0").format(bmi)
}
/**
* Menentukan kategori BMI
*/
internal fun calculateBMICategory(bmiString: String): String {
val bmi = bmiString.toDoubleOrNull() ?: 0.0
return when {
bmi < 18.5 -> "Underweight"
bmi < 25.0 -> "Normal weight"
bmi < 30.0 -> "Overweight"
bmi >= 30.0 -> "Obese"
else -> "Tidak diketahui"
}
}
/**
* Memberikan warna berdasarkan kategori BMI - menggunakan warna dari tema
*/
@Composable
fun getCategoryColor(category: String): androidx.compose.ui.graphics.Color {
return when (category) {
"Underweight" -> androidx.compose.ui.graphics.Color(0xFF2196F3) // Biru
"Normal weight" -> androidx.compose.ui.graphics.Color(0xFF4CAF50) // Hijau
"Overweight" -> androidx.compose.ui.graphics.Color(0xFFFF9800) // Orange
"Obese" -> androidx.compose.ui.graphics.Color(0xFFF44336) // Merah
else -> MaterialTheme.colorScheme.onSurface
} }
return NumberFormat.getCurrencyInstance().format(tip)
} }
@Preview(showBackground = true) @Preview(showBackground = true)

View File

@ -1,23 +0,0 @@
<!--
~ 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>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/app_icon_background"/>
<foreground android:drawable="@mipmap/app_icon_foreground"/>
</adaptive-icon>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/app_icon_background"/>
<foreground android:drawable="@mipmap/app_icon_foreground"/>
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

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

View File

@ -14,14 +14,10 @@
* 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.7.3" apply false id("com.android.application") version "8.13.0" apply false
id("com.android.library") version "8.7.3" apply false id("com.android.library") version "8.13.0" apply false
id("org.jetbrains.kotlin.android") version "1.9.10" apply false id("org.jetbrains.kotlin.android") version "2.1.0" 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.11.1-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

3
gradlew vendored
View File

@ -86,8 +86,7 @@ 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 APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
' "$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