Mantap UTS
This commit is contained in:
parent
099c35f19a
commit
cc9b2ad8c0
42
README.md
42
README.md
@ -1,10 +1,38 @@
|
||||
Kalkulator BMI
|
||||
===============
|
||||
# Kalkulator BMI
|
||||
|
||||
Silahkan kembangkan aplikasi ini untuk melakukan perhitungan BMI
|
||||
Aplikasi Android sederhana untuk menghitung Indeks Massa Tubuh (IMT) atau _Body Mass Index_ (BMI), dibuat dengan Kotlin dan Jetpack Compose.
|
||||
|
||||
Petunjuk lebih detil dapat dibaca di
|
||||
https://docs.google.com/document/d/1iGiC0Bg3Bdcd2Maq45TYkCDUkZ5Ql51E/edit?rtpof=true
|
||||
## Deskripsi
|
||||
|
||||
Starter dimodifikasi dan terinspirasi dari:
|
||||
https://developer.android.com/codelabs/basic-android-compose-calculate-tip#0
|
||||
Aplikasi ini memungkinkan pengguna untuk menghitung BMI mereka dengan memasukkan tinggi dan berat badan. Aplikasi mendukung dua sistem pengukuran:
|
||||
|
||||
1. **Sistem Internasional (SI)**: Menggunakan kilogram (kg) untuk berat dan sentimeter (cm) untuk tinggi.
|
||||
2. **US Customary (USC)**: Menggunakan pon (lbs) untuk berat dan inci (in) untuk tinggi.
|
||||
|
||||
Setelah menghitung, aplikasi akan menampilkan hasil BMI dan mengklasifikasikannya ke dalam salah satu dari empat kategori:
|
||||
* **Kekurangan Berat Badan**
|
||||
* **Normal**
|
||||
* **Kelebihan Berat Badan**
|
||||
* **Obesitas**
|
||||
|
||||
## Fitur Utama
|
||||
|
||||
* **Perhitungan BMI Akurat**: Mengimplementasikan formula standar BMI untuk kedua sistem unit.
|
||||
* **Antarmuka Modern**: Dibuat dengan Jetpack Compose, menampilkan input field yang bersih dan kartu hasil yang dinamis.
|
||||
* **Umpan Balik Visual**: Kartu hasil berubah warna sesuai dengan kategori BMI untuk memberikan indikasi visual yang cepat dan jelas.
|
||||
* **Pilihan Unit Fleksibel**: Pengguna dapat dengan mudah beralih antara sistem SI dan USC.
|
||||
* **Validasi Sederhana**: Menangani input kosong untuk mencegah error saat perhitungan.
|
||||
* **Kode Modular**: Kode dipecah menjadi beberapa komponen Composable yang dapat digunakan kembali (`BmiCalculatorScreen`, `EditNumberField`, `BmiResultCard`).
|
||||
* **Unit Testing**: Dilengkapi dengan unit test untuk memverifikasi logika perhitungan BMI dan penentuan kategori.
|
||||
|
||||
## Teknologi yang Digunakan
|
||||
|
||||
* **Bahasa Pemrograman**: Kotlin
|
||||
* **UI Toolkit**: Jetpack Compose
|
||||
* **Arsitektur**: Mengikuti prinsip-prinsip dasar _state management_ di Compose dengan _unidirectional data flow_.
|
||||
* **Asisten AI**: Proyek ini dikembangkan dengan bantuan **Gemini**, sebuah model bahasa besar dari Google, untuk pembuatan kode, refactoring, dokumentasi, dan debugging.
|
||||
|
||||
## Dibuat Oleh
|
||||
|
||||
* **Nama**: Yosep Gamaliel Mulia
|
||||
* **NPM**: 202310715105
|
||||
|
||||
@ -20,9 +20,9 @@
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:roundIcon="@drawable/ic_launcher"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.TipTime"
|
||||
tools:targetApi="33">
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
@ -13,6 +14,8 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
// NPM: 202310715105
|
||||
// Nama: Yosep Gamaliel Mulia
|
||||
package com.example.tiptime
|
||||
|
||||
import android.os.Bundle
|
||||
@ -21,52 +24,38 @@ import androidx.activity.compose.setContent
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.StringRes
|
||||
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.padding
|
||||
import androidx.compose.foundation.layout.safeDrawingPadding
|
||||
import androidx.compose.foundation.layout.statusBarsPadding
|
||||
import androidx.compose.foundation.layout.wrapContentWidth
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
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.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.example.tiptime.ui.theme.TipTimeTheme
|
||||
import java.text.NumberFormat
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.example.tiptime.ui.theme.BmiCalculatorTheme
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
enableEdgeToEdge()
|
||||
super.onCreate(savedInstanceState)
|
||||
setContent {
|
||||
TipTimeTheme {
|
||||
BmiCalculatorTheme {
|
||||
Surface(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
) {
|
||||
TipTimeLayout()
|
||||
BmiCalculatorScreen()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -74,68 +63,90 @@ class MainActivity : ComponentActivity() {
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun TipTimeLayout() {
|
||||
var amountInput by remember { mutableStateOf("") }
|
||||
var tipInput by remember { mutableStateOf("") }
|
||||
var roundUp by remember { mutableStateOf(false) }
|
||||
fun BmiCalculatorScreen() {
|
||||
var heightInput by remember { mutableStateOf("") }
|
||||
var weightInput by remember { mutableStateOf("") }
|
||||
var useUscUnits by remember { mutableStateOf(false) }
|
||||
var bmiResult by remember { mutableStateOf<Pair<Double, String>?>(null) }
|
||||
|
||||
val BmiHeight = amountInput.toDoubleOrNull() ?: 0.0
|
||||
val BmiWeight = tipInput.toDoubleOrNull() ?: 0.0
|
||||
val bmi = calculateBMI(BmiHeight, BmiWeight, roundUp)
|
||||
val category = calculateBMICategory(BmiHeight, BmiWeight, roundUp)
|
||||
val height = heightInput.toDoubleOrNull()
|
||||
val weight = weightInput.toDoubleOrNull()
|
||||
|
||||
val heightLabel = if (useUscUnits) R.string.height_in else R.string.height_cm
|
||||
val weightLabel = if (useUscUnits) R.string.weight_lbs else R.string.weight_kg
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.statusBarsPadding()
|
||||
.padding(horizontal = 40.dp)
|
||||
.fillMaxWidth()
|
||||
.verticalScroll(rememberScrollState())
|
||||
.safeDrawingPadding(),
|
||||
.safeDrawingPadding()
|
||||
.padding(32.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.calculate_tip),
|
||||
modifier = Modifier
|
||||
.padding(bottom = 16.dp, top = 40.dp)
|
||||
.align(alignment = Alignment.Start)
|
||||
text = stringResource(R.string.bmi_calculator_title),
|
||||
style = MaterialTheme.typography.displaySmall,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
// Input Fields
|
||||
Column(verticalArrangement = Arrangement.spacedBy(16.dp)) {
|
||||
EditNumberField(
|
||||
label = R.string.height,
|
||||
leadingIcon = R.drawable.number,
|
||||
label = heightLabel,
|
||||
leadingIcon = R.drawable.height,
|
||||
keyboardOptions = KeyboardOptions.Default.copy(
|
||||
keyboardType = KeyboardType.Number,
|
||||
imeAction = ImeAction.Next
|
||||
),
|
||||
value = amountInput,
|
||||
onValueChanged = { amountInput = it },
|
||||
modifier = Modifier.padding(bottom = 32.dp).fillMaxWidth(),
|
||||
value = heightInput,
|
||||
onValueChanged = { heightInput = it; bmiResult = null },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
EditNumberField(
|
||||
label = R.string.weight,
|
||||
leadingIcon = R.drawable.number,
|
||||
label = weightLabel,
|
||||
leadingIcon = R.drawable.weight,
|
||||
keyboardOptions = KeyboardOptions.Default.copy(
|
||||
keyboardType = KeyboardType.Number,
|
||||
imeAction = ImeAction.Done
|
||||
),
|
||||
value = tipInput,
|
||||
onValueChanged = { tipInput = it },
|
||||
modifier = Modifier.padding(bottom = 32.dp).fillMaxWidth(),
|
||||
value = weightInput,
|
||||
onValueChanged = { weightInput = it; bmiResult = null },
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
)
|
||||
RoundTheTipRow(
|
||||
roundUp = roundUp,
|
||||
onRoundUpChanged = { roundUp = it },
|
||||
modifier = Modifier.padding(bottom = 32.dp)
|
||||
)
|
||||
Text(
|
||||
text = stringResource(R.string.bmi_calculation, bmi),
|
||||
style = MaterialTheme.typography.displaySmall
|
||||
)
|
||||
Text(
|
||||
text = stringResource(R.string.bmi_category, category),
|
||||
style = MaterialTheme.typography.displaySmall
|
||||
UnitSelectionRow(
|
||||
useUsc = useUscUnits,
|
||||
onUscChanged = { useUscUnits = it; bmiResult = null },
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(150.dp))
|
||||
Button(
|
||||
onClick = {
|
||||
if (height != null && weight != null) {
|
||||
val bmi = calculateBmi(height, weight, useUscUnits)
|
||||
val category = getBmiCategory(bmi)
|
||||
bmiResult = Pair(bmi, category)
|
||||
}
|
||||
},
|
||||
colors = ButtonDefaults.buttonColors(containerColor = Color(0xFF50AADD)),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(50.dp)
|
||||
) {
|
||||
Text(
|
||||
stringResource(R.string.calculate_bmi_button),
|
||||
fontSize = 18.sp
|
||||
)
|
||||
}
|
||||
|
||||
// Result Display
|
||||
bmiResult?.let { (bmi, category) ->
|
||||
BmiResultCard(bmi = bmi, category = category)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -151,64 +162,114 @@ fun EditNumberField(
|
||||
TextField(
|
||||
value = value,
|
||||
singleLine = true,
|
||||
leadingIcon = { Icon(painter = painterResource(id = leadingIcon), null) },
|
||||
leadingIcon = {
|
||||
Icon(
|
||||
painter = painterResource(id = leadingIcon),
|
||||
contentDescription = null,
|
||||
tint = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
},
|
||||
modifier = modifier,
|
||||
onValueChange = onValueChanged,
|
||||
label = { Text(stringResource(label)) },
|
||||
keyboardOptions = keyboardOptions
|
||||
keyboardOptions = keyboardOptions,
|
||||
shape = MaterialTheme.shapes.medium,
|
||||
colors = TextFieldDefaults.colors(
|
||||
focusedIndicatorColor = Color.Transparent,
|
||||
unfocusedIndicatorColor = Color.Transparent
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun RoundTheTipRow(
|
||||
roundUp: Boolean,
|
||||
onRoundUpChanged: (Boolean) -> Unit,
|
||||
fun UnitSelectionRow(
|
||||
useUsc: Boolean,
|
||||
onUscChanged: (Boolean) -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Row(
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
Text(text = stringResource(R.string.use_usc))
|
||||
Text(text = stringResource(R.string.use_usc_units), style = MaterialTheme.typography.bodyLarge)
|
||||
Switch(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.wrapContentWidth(Alignment.End),
|
||||
checked = roundUp,
|
||||
onCheckedChange = onRoundUpChanged
|
||||
checked = useUsc,
|
||||
onCheckedChange = onUscChanged
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the BMI
|
||||
*
|
||||
* Catatan: tambahkan unit test untuk kalkulasi BMI ini
|
||||
*/
|
||||
private fun calculateBMI(BmiHeight: Double, BmiWeight: Double = 15.0, roundUp: Boolean): String {
|
||||
var bmi = BmiWeight / 100 * BmiHeight
|
||||
if (roundUp) {
|
||||
bmi = kotlin.math.ceil(bmi)
|
||||
@Composable
|
||||
fun BmiResultCard(bmi: Double, category: String, modifier: Modifier = Modifier) {
|
||||
val categoryColor = getCategoryColor(category)
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.clip(RoundedCornerShape(16.dp))
|
||||
.background(categoryColor)
|
||||
.padding(24.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.your_bmi),
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
color = Color.White
|
||||
)
|
||||
Text(
|
||||
text = bmi.format(1),
|
||||
style = MaterialTheme.typography.displayLarge,
|
||||
color = Color.White,
|
||||
modifier = Modifier.padding(vertical = 8.dp)
|
||||
)
|
||||
Text(
|
||||
text = category,
|
||||
style = MaterialTheme.typography.headlineSmall,
|
||||
color = Color.White
|
||||
)
|
||||
}
|
||||
return NumberFormat.getNumberInstance().format(bmi)
|
||||
}
|
||||
/**
|
||||
* Calculates the BMI Category
|
||||
*
|
||||
* Catatan: tambahkan unit test untuk kalkulasi BMI ini
|
||||
*/
|
||||
|
||||
private fun calculateBMICategory(BmiHeight: Double, BmiWeight: Double = 15.0, roundUp: Boolean): String {
|
||||
var bmi = BmiWeight / 100 * BmiHeight
|
||||
if (roundUp) {
|
||||
bmi = kotlin.math.ceil(bmi)
|
||||
private fun getCategoryColor(category: String): Color {
|
||||
return when (category) {
|
||||
"Kekurangan Berat Badan" -> Color(0xFF3D5AFE) // Blue
|
||||
"Normal" -> Color(0xFF00C853) // Green
|
||||
"Kelebihan Berat Badan" -> Color(0xFFFFAB00) // Amber
|
||||
"Obesitas" -> Color(0xFFD50000) // Red
|
||||
else -> Color.Gray
|
||||
}
|
||||
return NumberFormat.getNumberInstance().format(bmi)
|
||||
}
|
||||
|
||||
|
||||
internal fun calculateBmi(height: Double, weight: Double, useUscUnits: Boolean): Double {
|
||||
return if (height > 0 && weight > 0) {
|
||||
if (useUscUnits) {
|
||||
703 * weight / (height * height)
|
||||
} else {
|
||||
val heightInMeters = height / 100
|
||||
weight / (heightInMeters * heightInMeters)
|
||||
}
|
||||
} else {
|
||||
0.0
|
||||
}
|
||||
}
|
||||
|
||||
internal fun getBmiCategory(bmi: Double): String {
|
||||
return when {
|
||||
bmi < 18.5 -> "Kekurangan Berat Badan"
|
||||
bmi < 25 -> "Normal"
|
||||
bmi < 30 -> "Kelebihan Berat Badan"
|
||||
else -> "Obesitas"
|
||||
}
|
||||
}
|
||||
|
||||
private fun Double.format(digits: Int) = "%.${digits}f".format(this)
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
fun TipTimeLayoutPreview() {
|
||||
TipTimeTheme {
|
||||
TipTimeLayout()
|
||||
fun BmiCalculatorScreenPreview() {
|
||||
BmiCalculatorTheme {
|
||||
BmiCalculatorScreen()
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
package com.example.tiptime.ui.theme
|
||||
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
|
||||
@Composable
|
||||
fun BmiCalculatorTheme(
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
MaterialTheme(
|
||||
content = content
|
||||
)
|
||||
}
|
||||
9
app/src/main/res/drawable/height.xml
Normal file
9
app/src/main/res/drawable/height.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#8A8A8A"
|
||||
android:pathData="M16,7c0,2.21 -1.79,4 -4,4S8,9.21 8,7s1.79,-4 4,-4S16,4.79 16,7zM12,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z"/>
|
||||
</vector>
|
||||
36
app/src/main/res/drawable/ic_launcher.xml
Normal file
36
app/src/main/res/drawable/ic_launcher.xml
Normal file
@ -0,0 +1,36 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="1024dp"
|
||||
android:height="1024dp"
|
||||
android:viewportWidth="1024"
|
||||
android:viewportHeight="1024">
|
||||
<path
|
||||
android:pathData="M0,0C337.9,0 675.8,0 1024,0C1024,337.9 1024,675.8 1024,1024C686.1,1024 348.2,1024 0,1024C0,686.1 0,348.2 0,0Z"
|
||||
android:fillColor="#FEFEFE"/>
|
||||
<path
|
||||
android:pathData="M305.1,287.9C306.2,287.9 307.3,287.8 308.4,287.8C312,287.8 315.7,287.8 319.3,287.8C321.8,287.8 324.3,287.8 326.9,287.8C332.2,287.8 337.5,287.8 342.8,287.8C348.9,287.8 355,287.8 361.1,287.8C367,287.8 372.9,287.8 378.8,287.8C381.2,287.8 383.7,287.8 386.2,287.8C414.4,287.7 441.3,289.4 462.4,310.3C463.2,311.2 464.1,312.1 465,313C465.7,313.7 466.5,314.4 467.2,315.2C471.3,319.4 474.5,324.1 477.6,329.1C478,329.7 478.3,330.2 478.7,330.8C485.3,342 489.1,354.8 492.4,367.3C492.6,367.9 492.8,368.6 493,369.4C506.6,419.8 512.9,472.8 513.3,525C513.3,526.2 513.4,527.4 513.4,528.7C513.5,538 512.2,545.7 505.8,552.9C499.3,558.7 492.7,560.8 484,560.4C476.6,559.4 470.7,555.8 466.2,549.9C461.7,542.7 461,534.7 460.6,526.4C460.5,525.1 460.5,523.8 460.4,522.5C460.4,521.8 460.3,521.1 460.3,520.4C458.3,482.4 453.4,444.2 446.3,406.8C446,405.3 446,405.3 445.7,403.7C444.7,398.5 443.3,393.8 441,389C439.3,389 437.7,389 436,389C434.8,390 434.8,390 434.9,391.9C435,392.8 435,393.6 435,394.5C435.1,395.5 435.1,396.5 435.1,397.5C435.2,398.6 435.2,399.7 435.3,400.8C435.4,402.5 435.4,402.5 435.4,404.3C436.2,421 437.4,437.7 438.6,454.3C439.4,465.4 440.1,476.5 440.8,487.6C440.9,489.2 441,490.8 441.2,492.3C443.4,527.2 443.4,562.1 443.3,597C443.3,601 443.3,605.1 443.3,609.1C443.3,653.6 442.9,698 441.6,742.4C441.5,743.6 441.5,744.7 441.5,745.9C440.9,764 440.4,782 439.5,800.1C439.1,807.1 438.9,814.1 438.8,821.1C438.8,823 438.7,824.8 438.7,826.6C438.7,829.4 438.6,832.2 438.6,835C438.3,861.6 438.3,861.6 429,871C421.2,877 413.8,879 404,878C397.4,876.1 391.3,872.6 387.6,866.7C382.8,857.6 381.6,848.8 381,838.6C380.9,836.6 380.7,834.7 380.6,832.8C380.4,830.7 380.3,828.6 380.2,826.5C379.7,818.8 379.1,811.1 378.6,803.4C378.5,802.6 378.4,801.7 378.4,800.9C376.8,778.9 375,757 373.2,735.1C372.9,731.9 372.7,728.7 372.4,725.4C372.1,721.2 371.7,717 371.4,712.8C371.3,711.7 371.2,710.7 371.1,709.7C370.9,706.6 370.6,703.6 370.4,700.5C368.7,680.9 367.2,661.2 365.7,641.5C365.1,634.1 364.5,626.6 363.9,619.2C363.7,616.8 363.5,614.5 363.4,612.1C363.1,608.7 362.8,605.4 362.6,602C362.4,599.9 362.2,597.9 362.1,595.8C361.9,593.8 361.8,591.9 361.6,590C361.3,585.8 361,581.6 360.8,577.4C360.8,576.7 360.8,576 360.8,575.3C360.7,573.5 360.7,571.7 360.6,570C359.8,566 358.1,564.5 355,562C351.4,561.7 351.4,561.7 348,563C344.6,566.3 344.4,569.9 344.1,574.4C344,575.2 344,575.9 343.9,576.7C343.7,579.2 343.5,581.6 343.4,584.1C343.2,585.9 343.1,587.7 342.9,589.4C342.6,594.2 342.2,599 341.8,603.7C341.5,608.7 341.1,613.7 340.7,618.7C340,627.7 339.3,636.7 338.6,645.7C338,654.2 337.3,662.7 336.7,671.2C336.1,678.8 335.5,686.5 334.9,694.1C333.7,709.7 332.5,725.3 331.2,740.9C331.1,742.3 331.1,742.3 331,743.8C330.2,753.2 329.5,762.6 328.7,772C328.4,775.5 328.1,779 327.9,782.6C327.7,784.3 327.6,786 327.4,787.7C326.6,797.6 325.9,807.6 325.2,817.5C325.1,819.4 325,821.3 324.8,823.2C324.6,826.8 324.4,830.4 324.2,834C322.4,861.5 322.4,861.5 314,870C313.3,870.7 313.3,870.7 312.6,871.5C307.5,876.2 301.9,878.1 295.1,878.4C286.9,878.1 280.8,875.7 274.8,870.1C269.4,863.8 267,856.5 266.7,848.2C266.7,847.3 266.7,846.4 266.6,845.4C266.6,844.4 266.6,843.4 266.6,842.3C266.5,840.7 266.5,840.7 266.4,839.1C266.3,835.5 266.2,831.9 266.1,828.3C266,825.7 265.9,823.2 265.8,820.6C265.6,813.8 265.4,807 265.2,800.2C265.1,795.9 264.9,791.7 264.8,787.4C264.3,772 263.8,756.6 263.3,741.2C263.1,733.5 262.9,725.7 262.6,718C261.1,671 260.6,624 261,577C261,575.4 261,575.4 261,573.8C261.3,531.4 264.3,489 267.2,446.7C267.2,446 267.2,445.3 267.3,444.6C267.8,437.6 268.3,430.6 268.8,423.6C269.6,412.1 270.3,400.6 270,389C268.4,388.7 266.7,388.3 265,388C261.3,391.8 260.7,396.4 259.6,401.4C259.4,402.3 259.2,403.3 259,404.3C256.3,416.8 254.2,429.3 252.3,441.9C252,444 251.7,446.1 251.4,448.1C247.7,472 245.8,495.8 244.4,519.9C244.3,521.7 244.3,521.7 244.2,523.5C244.1,525.8 243.9,528 243.8,530.3C243.2,540.1 241.3,547.7 234.4,555C229.4,559.1 223.7,560.6 217.4,561.5C210,560.4 203.2,557.5 198,552C175.1,514.3 197.7,428.7 207.4,387.8C211.9,369.7 216.8,351.8 225,335C225.5,334 226,333 226.5,331.9C229.9,325.3 234.1,319.6 239,314C239.6,313.3 240.2,312.6 240.8,311.9C253,298.7 269.6,292 287,289C288.5,288.7 288.5,288.7 290,288.5C295,287.8 300,287.9 305.1,287.9Z"
|
||||
android:fillColor="#4EA8E3"/>
|
||||
<path
|
||||
android:pathData="M512.5,605.5C514.2,605.5 514.2,605.5 515.9,605.5C517.1,605.5 518.3,605.5 519.6,605.5C520.8,605.5 522,605.5 523.3,605.5C526,605.5 528.6,605.5 531.3,605.5C535.3,605.6 539.3,605.6 543.3,605.5C581.7,605.6 581.7,605.6 597,619C605.7,628.1 608.4,638.2 608.2,650.6C607.7,659.5 605.4,667.5 599,674C595.8,676.9 592.4,679.4 589,682C589.6,682.3 590.3,682.7 590.9,683C600.3,688.3 606.2,694.3 610.1,704.4C613.3,717.6 611.7,731 604.9,742.7C598.4,752.3 588.9,758.1 577.5,760.5C569.6,762 561.9,762.3 553.9,762.4C552.6,762.4 551.3,762.4 549.9,762.4C547.2,762.4 544.5,762.4 541.7,762.4C538.2,762.4 534.8,762.5 531.3,762.5C527.9,762.6 524.5,762.6 521.2,762.6C519.9,762.6 518.7,762.6 517.4,762.6C515.7,762.6 515.7,762.6 513.9,762.6C512.9,762.6 511.8,762.6 510.8,762.6C506.6,761.7 505.4,760.7 503,757C502.3,752.3 502.3,747.7 502.4,743C502.4,741.6 502.4,740.1 502.3,738.7C502.3,734.8 502.3,730.9 502.4,726.9C502.4,722.8 502.4,718.8 502.4,714.7C502.4,707.8 502.4,700.9 502.4,694C502.4,686.1 502.4,678.1 502.4,670.2C502.4,662.5 502.4,654.9 502.4,647.3C502.4,644 502.4,640.7 502.4,637.5C502.4,633.7 502.4,629.8 502.5,626C502.5,624.6 502.5,623.2 502.5,621.8C502.4,619.9 502.5,617.9 502.5,616C502.5,615 502.5,613.9 502.5,612.8C503.5,607 507.1,605.5 512.5,605.5Z"
|
||||
android:fillColor="#4CA7E3"/>
|
||||
<path
|
||||
android:pathData="M646.2,605.4C648,605.4 648,605.4 649.8,605.4C651,605.4 652.2,605.4 653.5,605.4C654.7,605.4 655.9,605.4 657.2,605.4C667.4,605.5 667.4,605.5 672,610C673.5,612.6 674.5,615.3 675.6,618.1C675.9,618.9 676.2,619.7 676.6,620.5C677.6,623.2 678.7,625.9 679.7,628.5C680.4,630.4 681.2,632.3 681.9,634.1C683.8,639 685.7,643.9 687.6,648.8C689.6,653.7 691.6,658.7 693.5,663.7C697.4,673.5 701.2,683.2 705,693C707.1,690.9 707.7,689.5 708.8,686.7C709.1,685.8 709.5,684.9 709.8,683.9C710.4,682.5 710.4,682.5 710.9,681C711.3,679.9 711.7,678.9 712.1,677.9C712.9,675.7 713.8,673.4 714.6,671.2C715.9,667.8 717.2,664.4 718.5,661C722,651.7 725.5,642.5 728.9,633.2C730,630.3 731.1,627.5 732.1,624.6C732.6,623.3 733.1,622 733.6,620.7C734.2,618.9 734.9,617.2 735.6,615.4C735.9,614.5 736.3,613.5 736.6,612.5C738.3,609.4 740,607.9 743,606C746.1,605.5 746.1,605.5 749.5,605.5C750.7,605.5 751.9,605.5 753.2,605.5C754.5,605.5 755.7,605.5 757.1,605.5C758.3,605.5 759.6,605.5 760.9,605.5C762.2,605.5 763.4,605.5 764.7,605.5C766.3,605.5 766.3,605.5 768.1,605.5C771.6,606.1 772.8,607.2 775,610C776.4,612.8 776.2,615.1 776.3,618.2C776.3,618.9 776.3,619.5 776.3,620.2C776.4,622.3 776.4,624.5 776.5,626.7C776.5,628.2 776.6,629.7 776.6,631.2C776.7,635.3 776.8,639.4 776.9,643.5C777,646.9 777.1,650.3 777.2,653.7C777.7,673.7 778.2,693.7 778.6,713.8C778.6,714.7 778.7,715.6 778.7,716.6C778.8,721 778.9,725.4 778.9,729.8C779,733.5 779.1,737.3 779.2,741C779.2,743 779.3,745 779.3,747C779.4,747.9 779.4,748.9 779.5,749.8C779.5,754.3 779.5,756.3 776.8,760.1C773.9,762 772.7,762.6 769.3,762.7C768.4,762.7 767.6,762.7 766.7,762.7C765.8,762.7 764.9,762.6 764,762.6C763.1,762.6 762.2,762.7 761.3,762.7C760.4,762.7 759.6,762.7 758.7,762.7C757.9,762.7 757.1,762.7 756.3,762.6C752.7,761.6 751.3,759.9 749,757C748.3,753.8 748.3,750.7 748.3,747.4C748.3,746.5 748.3,745.5 748.3,744.5C748.3,741.4 748.3,738.2 748.3,735.1C748.3,732.9 748.3,730.7 748.2,728.5C748.2,722.7 748.2,717 748.2,711.2C748.2,705.3 748.1,699.5 748.1,693.6C748,682.1 748,670.5 748,659C747.8,659.6 747.5,660.2 747.3,660.8C742.8,672.1 738.4,683.3 733.9,694.5C731.4,701 728.8,707.5 726.3,714.1C725.5,716 724.7,717.9 724,719.9C723.1,722.1 722.2,724.3 721.4,726.6C718.7,733.4 718.7,733.4 715.7,736.1C712.1,737.3 708.7,737.5 705,737.4C704.3,737.5 703.6,737.5 702.9,737.5C697.8,737.5 695.6,736.4 692,733C690.5,730.2 690.5,730.2 689.2,727C688.7,725.8 688.2,724.6 687.8,723.4C687.2,722.1 686.7,720.8 686.2,719.5C685.7,718.1 685.1,716.8 684.6,715.4C683.2,711.8 681.8,708.3 680.4,704.7C678.9,701.1 677.5,697.5 676.1,693.9C674.5,689.8 672.9,685.8 671.2,681.7C668.3,674.1 665.2,666.5 662,659C662,660.2 662,661.4 662,662.7C662,674.1 661.9,685.6 661.9,697.1C661.8,703 661.8,708.9 661.8,714.8C661.8,720.4 661.8,726.1 661.7,731.8C661.7,734 661.7,736.2 661.7,738.3C661.7,741.4 661.7,744.4 661.7,747.4C661.7,748.3 661.7,749.2 661.7,750.2C661.6,754.6 661.4,756.4 658.6,760.1C655.9,762.1 654.8,762.6 651.5,762.7C650.7,762.7 649.9,762.7 649.1,762.7C648.2,762.7 647.4,762.6 646.5,762.6C645.7,762.6 644.8,762.7 643.9,762.7C639.8,762.7 637.5,762.3 633.9,760.1C631.1,755.5 631.4,751.6 631.6,746.3C631.6,745.1 631.7,743.9 631.7,742.7C631.7,740 631.8,737.3 631.9,734.6C632,729.6 632.1,724.7 632.2,719.8C632.3,710.6 632.5,701.4 632.7,692.2C632.9,684.7 633.1,677.2 633.2,669.6C633.3,663.2 633.5,656.8 633.6,650.4C633.7,646.4 633.8,642.5 633.8,638.5C633.9,634.7 634,631 634.1,627.2C634.1,625.8 634.1,624.4 634.1,623C634.3,612.2 634.3,612.2 637.2,607.7C640.5,605.7 642.4,605.4 646.2,605.4Z"
|
||||
android:fillColor="#4DA7E3"/>
|
||||
<path
|
||||
android:pathData="M374,149C374.9,149.4 374.9,149.4 375.8,149.8C394.3,157.6 405.8,169.9 413.7,188.4C419.9,205.9 418,223.6 410.3,240.3C402,255.8 388.9,267.1 372.1,272.4C355.6,277.1 338.8,276.4 323.5,268.3C306.7,259 295.1,244.4 289.5,226.1C285.1,208.4 288.7,190.3 297.8,174.9C306.8,160.8 321.1,150.9 337.2,146.9C348.7,144.5 363.1,144.4 374,149Z"
|
||||
android:fillColor="#4EA7E3"/>
|
||||
<path
|
||||
android:pathData="M818.9,605.4C819.9,605.4 820.8,605.4 821.7,605.4C822.7,605.4 823.6,605.4 824.6,605.4C826,605.4 826,605.4 827.4,605.4C834.3,605.5 834.3,605.5 837.6,607.9C840,611.4 840.1,613.5 840.2,617.7C840.2,618.9 840.2,620.1 840.2,621.4C840.2,622.7 840.2,624.1 840.2,625.5C840.2,626.9 840.2,628.3 840.2,629.7C840.2,634.4 840.3,639.1 840.3,643.7C840.3,645.3 840.3,647 840.3,648.6C840.3,655.2 840.3,661.9 840.3,668.6C840.4,678.2 840.4,687.8 840.4,697.4C840.5,704.1 840.5,710.9 840.5,717.6C840.5,721.6 840.5,725.7 840.6,729.7C840.6,733.5 840.6,737.3 840.6,741C840.6,742.4 840.6,743.8 840.6,745.2C840.8,757 840.8,757 837.6,760.3C834.9,762.1 833.5,762.6 830.3,762.6C829,762.5 829,762.5 827.6,762.5C826.8,762.5 825.9,762.5 824.9,762.4C824,762.4 823.1,762.4 822.2,762.4C814.4,762.3 814.4,762.3 811,760C808.9,756.7 808.7,753.9 808.7,750C808.7,748.8 808.7,747.6 808.7,746.4C808.7,745 808.7,743.7 808.7,742.3C808.7,740.9 808.7,739.5 808.7,738.1C808.6,734.2 808.6,730.3 808.6,726.5C808.6,724.1 808.6,721.7 808.6,719.2C808.6,710.8 808.6,702.4 808.6,694C808.6,686.2 808.5,678.3 808.5,670.5C808.5,663.8 808.4,657 808.4,650.3C808.4,646.3 808.4,642.3 808.4,638.3C808.4,634.5 808.4,630.7 808.4,626.9C808.4,625.5 808.4,624.1 808.4,622.8C808.2,611 808.2,611 811.4,607.7C814.2,605.9 815.6,605.4 818.9,605.4Z"
|
||||
android:fillColor="#4BA6E2"/>
|
||||
<path
|
||||
android:pathData="M533,695C537.9,694.9 542.9,694.9 547.9,694.8C549.5,694.8 551,694.8 552.6,694.7C569.1,694.6 569.1,694.6 574.9,699.6C579.3,704.3 580.7,709.1 581.3,715.4C580.8,721.1 579.3,725.3 575.8,729.8C567.5,736.3 558.5,735.4 548.5,735.2C543.4,735.1 538.3,735.1 533,735C533,721.8 533,708.6 533,695Z"
|
||||
android:fillColor="#FDFEFE"/>
|
||||
<path
|
||||
android:pathData="M546.9,631.8C548.1,631.7 549.3,631.7 550.6,631.7C566.9,631.6 566.9,631.6 572.6,636.3C577.1,641.4 578.4,646.1 578.2,652.7C577.7,657.9 576.2,662.3 572.2,665.9C566.9,669.4 562.4,670.3 556.1,670.2C554.8,670.2 553.5,670.2 552.2,670.2C551.6,670.2 550.9,670.2 550.2,670.2C548.2,670.2 546.1,670.2 544.1,670.2C534.1,670.1 534.1,670.1 533,669C532.9,666.3 532.9,663.7 532.9,661.1C532.9,660.3 532.9,659.5 532.9,658.7C532.9,657 532.9,655.3 532.9,653.6C532.9,651 532.9,648.4 532.9,645.8C532.9,644.2 532.9,642.6 532.9,640.9C532.9,640.2 532.9,639.4 532.9,638.6C532.9,629.1 538.8,631.8 546.9,631.8Z"
|
||||
android:fillColor="#FDFEFE"/>
|
||||
<path
|
||||
android:pathData="M245,308C245.7,308.3 246.3,308.7 247,309C239.7,317.4 239.7,317.4 236,321C235.3,320.7 234.7,320.3 234,320C235.5,318.4 236.9,316.7 238.4,315.1C239.2,314.2 240,313.3 240.8,312.4C242.2,310.9 243.6,309.4 245,308Z"
|
||||
android:fillColor="#3C9FE1"/>
|
||||
<path
|
||||
android:pathData="M297,177C297.8,178.6 297.8,178.6 298,181C296.1,184.3 296.1,184.3 294,187C293,184 293,184 293.8,182.2C294.9,180.5 295.9,178.7 297,177Z"
|
||||
android:fillColor="#369DE0"/>
|
||||
</vector>
|
||||
9
app/src/main/res/drawable/weight.xml
Normal file
9
app/src/main/res/drawable/weight.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#8A8A8A"
|
||||
android:pathData="M9,4v1h6V4c0,-1.1 -0.9,-2 -2,-2h-2c-1.1,0 -2,0.9 -2,2zM12,10c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2zM19,12c-1.68,0 -3.11,0.99 -3.71,2.44L12,17.42l-3.29,-2.98C8.11,12.99 6.68,12 5,12c-2.76,0 -5,2.24 -5,5v2h24v-2c0,-2.76 -2.24,-5 -5,-5z"/>
|
||||
</vector>
|
||||
@ -1,25 +1,16 @@
|
||||
<?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.
|
||||
-->
|
||||
<resources>
|
||||
<string name="app_name">BMI Calculator</string>
|
||||
<string name="calculate_tip">Calculate BMI</string>
|
||||
<string name="height">Tinggi Badan</string>
|
||||
<string name="weight">Berat Badan</string>
|
||||
<string name="use_usc">Gunakan Unit USC (lbs/in)?</string>
|
||||
<string name="bmi_calculation">BMI Anda: %s</string>
|
||||
<string name="bmi_category">Kategori: %s</string>
|
||||
<string name="app_name">Kalkulator BMI</string>
|
||||
<string name="bmi_calculator_title">Kalkulator BMI</string>
|
||||
<string name="height_in">Tinggi (inci)</string>
|
||||
<string name="height_cm">Tinggi (cm)</string>
|
||||
<string name="weight_lbs">Berat (pon)</string>
|
||||
<string name="weight_kg">Berat (kg)</string>
|
||||
<string name="use_usc_units">Gunakan unit USC</string>
|
||||
<string name="bmi_result">BMI Anda: %s</string>
|
||||
<string name="bmi_category_result">Kategori: %s</string>
|
||||
<string name="height">Tinggi</string>
|
||||
<string name="weight">Berat</string>
|
||||
<string name="calculate_bmi_button">Hitung BMI</string>
|
||||
<string name="your_bmi">BMI Anda</string>
|
||||
</resources>
|
||||
Loading…
x
Reference in New Issue
Block a user