UTS-202310715082-FazriAbdurrahman
This commit is contained in:
parent
099c35f19a
commit
de59cc8f47
@ -1,18 +1,3 @@
|
|||||||
/*
|
|
||||||
* 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
|
||||||
@ -21,7 +6,9 @@ import androidx.activity.compose.setContent
|
|||||||
import androidx.activity.enableEdgeToEdge
|
import androidx.activity.enableEdgeToEdge
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
|
import androidx.compose.foundation.Canvas
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
@ -30,17 +17,18 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.safeDrawingPadding
|
import androidx.compose.foundation.layout.safeDrawingPadding
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.statusBarsPadding
|
import androidx.compose.foundation.layout.statusBarsPadding
|
||||||
import androidx.compose.foundation.layout.wrapContentWidth
|
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.OutlinedTextField
|
||||||
|
import androidx.compose.material3.OutlinedTextFieldDefaults
|
||||||
import androidx.compose.material3.Surface
|
import androidx.compose.material3.Surface
|
||||||
import androidx.compose.material3.Switch
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TextField
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
@ -48,14 +36,20 @@ import androidx.compose.runtime.remember
|
|||||||
import androidx.compose.runtime.setValue
|
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.geometry.Offset
|
||||||
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.graphics.StrokeCap
|
||||||
|
import androidx.compose.ui.graphics.drawscope.Stroke
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.input.ImeAction
|
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 com.example.tiptime.ui.theme.TipTimeTheme
|
import com.example.tiptime.ui.theme.TipTimeTheme
|
||||||
import java.text.NumberFormat
|
import kotlin.math.cos
|
||||||
|
import kotlin.math.sin
|
||||||
|
|
||||||
class MainActivity : ComponentActivity() {
|
class MainActivity : ComponentActivity() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
@ -65,8 +59,9 @@ class MainActivity : ComponentActivity() {
|
|||||||
TipTimeTheme {
|
TipTimeTheme {
|
||||||
Surface(
|
Surface(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
color = MaterialTheme.colorScheme.background
|
||||||
) {
|
) {
|
||||||
TipTimeLayout()
|
BmiCalculatorScreen()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -74,68 +69,60 @@ class MainActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun TipTimeLayout() {
|
fun BmiCalculatorScreen() {
|
||||||
var amountInput by remember { mutableStateOf("") }
|
var heightInput by remember { mutableStateOf("175") } // Default for preview
|
||||||
var tipInput by remember { mutableStateOf("") }
|
var weightInput by remember { mutableStateOf("70") } // Default for preview
|
||||||
var roundUp by remember { mutableStateOf(false) }
|
var ageInput by remember { mutableStateOf("25") }
|
||||||
|
|
||||||
val BmiHeight = amountInput.toDoubleOrNull() ?: 0.0
|
val heightCm = heightInput.toDoubleOrNull() ?: 0.0
|
||||||
val BmiWeight = tipInput.toDoubleOrNull() ?: 0.0
|
val weightKg = weightInput.toDoubleOrNull() ?: 0.0
|
||||||
val bmi = calculateBMI(BmiHeight, BmiWeight, roundUp)
|
|
||||||
val category = calculateBMICategory(BmiHeight, BmiWeight, roundUp)
|
val bmi = calculateBMI(heightCm, weightKg)
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.statusBarsPadding()
|
.statusBarsPadding()
|
||||||
.padding(horizontal = 40.dp)
|
.padding(horizontal = 24.dp)
|
||||||
.verticalScroll(rememberScrollState())
|
.verticalScroll(rememberScrollState())
|
||||||
.safeDrawingPadding(),
|
.safeDrawingPadding(),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
verticalArrangement = Arrangement.Center
|
verticalArrangement = Arrangement.Top
|
||||||
) {
|
) {
|
||||||
|
Spacer(modifier = Modifier.height(20.dp))
|
||||||
Text(
|
Text(
|
||||||
text = stringResource(R.string.calculate_tip),
|
text = stringResource(R.string.calculate_tip),
|
||||||
modifier = Modifier
|
style = MaterialTheme.typography.headlineMedium,
|
||||||
.padding(bottom = 16.dp, top = 40.dp)
|
color = MaterialTheme.colorScheme.primary
|
||||||
.align(alignment = Alignment.Start)
|
|
||||||
)
|
)
|
||||||
|
Spacer(modifier = Modifier.height(24.dp))
|
||||||
|
|
||||||
EditNumberField(
|
EditNumberField(
|
||||||
label = R.string.height,
|
label = R.string.height,
|
||||||
leadingIcon = R.drawable.number,
|
leadingIcon = R.drawable.number,
|
||||||
keyboardOptions = KeyboardOptions.Default.copy(
|
value = heightInput,
|
||||||
keyboardType = KeyboardType.Number,
|
onValueChanged = { heightInput = it },
|
||||||
imeAction = ImeAction.Next
|
|
||||||
),
|
|
||||||
value = amountInput,
|
|
||||||
onValueChanged = { amountInput = it },
|
|
||||||
modifier = Modifier.padding(bottom = 32.dp).fillMaxWidth(),
|
|
||||||
)
|
)
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
EditNumberField(
|
EditNumberField(
|
||||||
label = R.string.weight,
|
label = R.string.weight,
|
||||||
leadingIcon = R.drawable.number,
|
leadingIcon = R.drawable.number,
|
||||||
keyboardOptions = KeyboardOptions.Default.copy(
|
value = weightInput,
|
||||||
keyboardType = KeyboardType.Number,
|
onValueChanged = { weightInput = it },
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
EditNumberField(
|
||||||
|
label = R.string.age,
|
||||||
|
leadingIcon = R.drawable.number,
|
||||||
|
value = ageInput,
|
||||||
|
onValueChanged = { ageInput = it },
|
||||||
imeAction = ImeAction.Done
|
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 = stringResource(R.string.bmi_calculation, bmi),
|
|
||||||
style = MaterialTheme.typography.displaySmall
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
text = stringResource(R.string.bmi_category, category),
|
|
||||||
style = MaterialTheme.typography.displaySmall
|
|
||||||
)
|
)
|
||||||
|
Spacer(modifier = Modifier.height(32.dp))
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(150.dp))
|
if (bmi > 0) {
|
||||||
|
ResultScreen(bmi = bmi, heightCm = heightCm, weightKg = weightKg)
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.height(20.dp))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,72 +130,162 @@ fun TipTimeLayout() {
|
|||||||
fun EditNumberField(
|
fun EditNumberField(
|
||||||
@StringRes label: Int,
|
@StringRes label: Int,
|
||||||
@DrawableRes leadingIcon: Int,
|
@DrawableRes leadingIcon: Int,
|
||||||
keyboardOptions: KeyboardOptions,
|
|
||||||
value: String,
|
value: String,
|
||||||
onValueChanged: (String) -> Unit,
|
onValueChanged: (String) -> Unit,
|
||||||
modifier: Modifier = Modifier
|
imeAction: ImeAction = ImeAction.Next
|
||||||
) {
|
) {
|
||||||
TextField(
|
OutlinedTextField(
|
||||||
value = value,
|
value = value,
|
||||||
singleLine = true,
|
singleLine = true,
|
||||||
leadingIcon = { Icon(painter = painterResource(id = leadingIcon), null) },
|
modifier = Modifier.fillMaxWidth(),
|
||||||
modifier = modifier,
|
|
||||||
onValueChange = onValueChanged,
|
onValueChange = onValueChanged,
|
||||||
label = { Text(stringResource(label)) },
|
label = { Text(stringResource(label)) },
|
||||||
keyboardOptions = keyboardOptions
|
leadingIcon = { Icon(painter = painterResource(id = leadingIcon), null) },
|
||||||
|
keyboardOptions = KeyboardOptions.Default.copy(
|
||||||
|
keyboardType = KeyboardType.Number,
|
||||||
|
imeAction = imeAction
|
||||||
|
),
|
||||||
|
shape = RoundedCornerShape(16.dp),
|
||||||
|
colors = OutlinedTextFieldDefaults.colors(
|
||||||
|
focusedBorderColor = MaterialTheme.colorScheme.primary,
|
||||||
|
unfocusedBorderColor = MaterialTheme.colorScheme.outline
|
||||||
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun RoundTheTipRow(
|
fun ResultScreen(bmi: Double, heightCm: Double, weightKg: Double) {
|
||||||
roundUp: Boolean,
|
val category = getBmiCategory(bmi)
|
||||||
onRoundUpChanged: (Boolean) -> Unit,
|
val (healthyWeightMin, healthyWeightMax) = calculateHealthyWeightRange(heightCm)
|
||||||
modifier: Modifier = Modifier
|
val bmiPrime = calculateBmiPrime(bmi)
|
||||||
) {
|
val ponderalIndex = calculatePonderalIndex(heightCm, weightKg)
|
||||||
Row(
|
|
||||||
modifier = modifier.fillMaxWidth(),
|
Column(
|
||||||
verticalAlignment = Alignment.CenterVertically
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
) {
|
) {
|
||||||
Text(text = stringResource(R.string.use_usc))
|
Text(
|
||||||
Switch(
|
text = stringResource(R.string.result_title),
|
||||||
modifier = Modifier
|
style = MaterialTheme.typography.headlineSmall,
|
||||||
.fillMaxWidth()
|
color = MaterialTheme.colorScheme.primary
|
||||||
.wrapContentWidth(Alignment.End),
|
)
|
||||||
checked = roundUp,
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
onCheckedChange = onRoundUpChanged
|
Text(
|
||||||
|
text = stringResource(R.string.bmi_value_category, bmi, category),
|
||||||
|
style = MaterialTheme.typography.titleLarge,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
color = MaterialTheme.colorScheme.primary
|
||||||
|
)
|
||||||
|
Spacer(modifier = Modifier.height(24.dp))
|
||||||
|
|
||||||
|
BmiGaugeChart(bmi = bmi)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(24.dp))
|
||||||
|
|
||||||
|
Column(modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.Start) {
|
||||||
|
ResultInfoLine(label = stringResource(R.string.healthy_bmi_range))
|
||||||
|
ResultInfoLine(label = stringResource(R.string.healthy_weight_for_height, healthyWeightMin, healthyWeightMax))
|
||||||
|
ResultInfoLine(label = stringResource(R.string.bmi_prime, bmiPrime))
|
||||||
|
ResultInfoLine(label = stringResource(R.string.ponderal_index, ponderalIndex))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ResultInfoLine(label: String) {
|
||||||
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
|
Text(text = "• ", color = MaterialTheme.colorScheme.onSurface)
|
||||||
|
Text(text = label, style = MaterialTheme.typography.bodyLarge, color = MaterialTheme.colorScheme.onSurface)
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.height(4.dp))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun BmiGaugeChart(bmi: Double) {
|
||||||
|
val bmiMin = 16.0
|
||||||
|
val bmiMax = 40.0
|
||||||
|
|
||||||
|
val colors = listOf(
|
||||||
|
Color(0xFFD32F2F), // Underweight
|
||||||
|
Color(0xFF388E3C), // Normal
|
||||||
|
Color(0xFFFBC02D), // Overweight
|
||||||
|
Color(0xFFC62828) // Obesity
|
||||||
|
)
|
||||||
|
|
||||||
|
val onSurfaceColor = MaterialTheme.colorScheme.onSurface
|
||||||
|
|
||||||
|
Box(contentAlignment = Alignment.Center, modifier = Modifier.size(280.dp)) {
|
||||||
|
Canvas(modifier = Modifier.fillMaxSize()) {
|
||||||
|
val strokeWidth = 30.dp.toPx()
|
||||||
|
val center = Offset(size.width / 2, size.height / 2)
|
||||||
|
val radius = (size.minDimension / 2) - strokeWidth
|
||||||
|
|
||||||
|
val scale = 180f / (bmiMax - bmiMin).toFloat()
|
||||||
|
val underweightSweep = (18.5f - bmiMin.toFloat()) * scale
|
||||||
|
val normalSweep = (25f - 18.5f) * scale
|
||||||
|
val overweightSweep = (30f - 25f) * scale
|
||||||
|
val obesitySweep = (bmiMax.toFloat() - 30f) * scale
|
||||||
|
|
||||||
|
drawArc(colors[0], 180f, underweightSweep, false, style = Stroke(width = strokeWidth))
|
||||||
|
drawArc(colors[1], 180f + underweightSweep, normalSweep, false, style = Stroke(width = strokeWidth))
|
||||||
|
drawArc(colors[2], 180f + underweightSweep + normalSweep, overweightSweep, false, style = Stroke(width = strokeWidth))
|
||||||
|
drawArc(colors[3], 180f + underweightSweep + normalSweep + overweightSweep, obesitySweep, false, style = Stroke(width = strokeWidth))
|
||||||
|
|
||||||
|
val angle = 180 + (180 * ((bmi.coerceIn(bmiMin, bmiMax) - bmiMin) / (bmiMax - bmiMin))).toFloat()
|
||||||
|
val needleLength = radius - 10.dp.toPx()
|
||||||
|
val needleEndX = center.x + needleLength * cos(Math.toRadians(angle.toDouble())).toFloat()
|
||||||
|
val needleEndY = center.y + needleLength * sin(Math.toRadians(angle.toDouble())).toFloat()
|
||||||
|
|
||||||
|
drawLine(onSurfaceColor, center, Offset(needleEndX, needleEndY), 3.dp.toPx(), StrokeCap.Round)
|
||||||
|
drawCircle(onSurfaceColor, 5.dp.toPx(), center)
|
||||||
|
}
|
||||||
|
|
||||||
|
Text(
|
||||||
|
text = "BMI = %.1f".format(bmi),
|
||||||
|
style = MaterialTheme.typography.headlineLarge,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
color = onSurfaceColor
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private fun calculateBMI(heightCm: Double, weightKg: Double): Double {
|
||||||
* Calculates the BMI
|
if (heightCm <= 0 || weightKg <= 0) return 0.0
|
||||||
*
|
val heightInMeters = heightCm / 100.0
|
||||||
* Catatan: tambahkan unit test untuk kalkulasi BMI ini
|
return weightKg / (heightInMeters * heightInMeters)
|
||||||
*/
|
|
||||||
private fun calculateBMI(BmiHeight: Double, BmiWeight: Double = 15.0, roundUp: Boolean): String {
|
|
||||||
var bmi = BmiWeight / 100 * BmiHeight
|
|
||||||
if (roundUp) {
|
|
||||||
bmi = kotlin.math.ceil(bmi)
|
|
||||||
}
|
|
||||||
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 {
|
private fun getBmiCategory(bmi: Double): String {
|
||||||
var bmi = BmiWeight / 100 * BmiHeight
|
return when {
|
||||||
if (roundUp) {
|
bmi < 18.5 -> "Underweight"
|
||||||
bmi = kotlin.math.ceil(bmi)
|
bmi < 25 -> "Normal"
|
||||||
|
bmi < 30 -> "Overweight"
|
||||||
|
else -> "Obese"
|
||||||
}
|
}
|
||||||
return NumberFormat.getNumberInstance().format(bmi)
|
|
||||||
}
|
}
|
||||||
@Preview(showBackground = true)
|
|
||||||
|
private fun calculateHealthyWeightRange(heightCm: Double): Pair<Double, Double> {
|
||||||
|
if (heightCm <= 0) return 0.0 to 0.0
|
||||||
|
val heightInMeters = heightCm / 100.0
|
||||||
|
val minWeight = 18.5 * heightInMeters * heightInMeters
|
||||||
|
val maxWeight = 24.9 * heightInMeters * heightInMeters
|
||||||
|
return minWeight to maxWeight
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun calculateBmiPrime(bmi: Double): Double {
|
||||||
|
return if (bmi > 0) bmi / 25.0 else 0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun calculatePonderalIndex(heightCm: Double, weightKg: Double): Double {
|
||||||
|
if (heightCm <= 0 || weightKg <= 0) return 0.0
|
||||||
|
val heightInMeters = heightCm / 100.0
|
||||||
|
return weightKg / (heightInMeters * heightInMeters * heightInMeters)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview(showBackground = true, widthDp = 380)
|
||||||
@Composable
|
@Composable
|
||||||
fun TipTimeLayoutPreview() {
|
fun BmiCalculatorScreenPreview() {
|
||||||
TipTimeTheme {
|
TipTimeTheme {
|
||||||
TipTimeLayout()
|
BmiCalculatorScreen()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,78 +1,71 @@
|
|||||||
/*
|
|
||||||
* 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.ui.theme
|
package com.example.tiptime.ui.theme
|
||||||
|
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
|
||||||
val md_theme_light_primary = Color(0xFF984061)
|
// Custom Army Green & Brown Palette
|
||||||
val md_theme_light_onPrimary = Color(0xFFFFFFFF)
|
val armyGreen = Color(0xFF4B5320)
|
||||||
val md_theme_light_primaryContainer = Color(0xFFFFD9E2)
|
val darkBrown = Color(0xFF5C4033)
|
||||||
val md_theme_light_onPrimaryContainer = Color(0xFF3E001D)
|
val lightCream = Color(0xFFF5F5DC)
|
||||||
val md_theme_light_secondary = Color(0xFF754B9C)
|
val tan = Color(0xFFD2B48C)
|
||||||
val md_theme_light_onSecondary = Color(0xFFFFFFFF)
|
|
||||||
val md_theme_light_secondaryContainer = Color(0xFFF1DBFF)
|
// Material 3 Light Theme Colors
|
||||||
val md_theme_light_onSecondaryContainer = Color(0xFF2D0050)
|
val md_theme_light_primary = armyGreen
|
||||||
val md_theme_light_tertiary = Color(0xFF984060)
|
val md_theme_light_onPrimary = lightCream
|
||||||
val md_theme_light_onTertiary = Color(0xFFFFFFFF)
|
val md_theme_light_primaryContainer = tan
|
||||||
val md_theme_light_tertiaryContainer = Color(0xFFFFD9E2)
|
val md_theme_light_onPrimaryContainer = darkBrown
|
||||||
val md_theme_light_onTertiaryContainer = Color(0xFF3E001D)
|
val md_theme_light_secondary = darkBrown
|
||||||
|
val md_theme_light_onSecondary = lightCream
|
||||||
|
val md_theme_light_secondaryContainer = tan
|
||||||
|
val md_theme_light_onSecondaryContainer = darkBrown
|
||||||
|
val md_theme_light_tertiary = tan
|
||||||
|
val md_theme_light_onTertiary = darkBrown
|
||||||
|
val md_theme_light_tertiaryContainer = armyGreen
|
||||||
|
val md_theme_light_onTertiaryContainer = lightCream
|
||||||
val md_theme_light_error = Color(0xFFBA1A1A)
|
val md_theme_light_error = Color(0xFFBA1A1A)
|
||||||
val md_theme_light_errorContainer = Color(0xFFFFDAD6)
|
val md_theme_light_errorContainer = Color(0xFFFFDAD6)
|
||||||
val md_theme_light_onError = Color(0xFFFFFFFF)
|
val md_theme_light_onError = Color(0xFFFFFFFF)
|
||||||
val md_theme_light_onErrorContainer = Color(0xFF410002)
|
val md_theme_light_onErrorContainer = Color(0xFF410002)
|
||||||
val md_theme_light_background = Color(0xFFFAFCFF)
|
val md_theme_light_background = lightCream
|
||||||
val md_theme_light_onBackground = Color(0xFF001F2A)
|
val md_theme_light_onBackground = darkBrown
|
||||||
val md_theme_light_surface = Color(0xFFFAFCFF)
|
val md_theme_light_surface = lightCream
|
||||||
val md_theme_light_onSurface = Color(0xFF001F2A)
|
val md_theme_light_onSurface = darkBrown
|
||||||
val md_theme_light_surfaceVariant = Color(0xFFF2DDE2)
|
val md_theme_light_surfaceVariant = tan
|
||||||
val md_theme_light_onSurfaceVariant = Color(0xFF514347)
|
val md_theme_light_onSurfaceVariant = darkBrown
|
||||||
val md_theme_light_outline = Color(0xFF837377)
|
val md_theme_light_outline = armyGreen
|
||||||
val md_theme_light_inverseOnSurface = Color(0xFFE1F4FF)
|
val md_theme_light_inverseOnSurface = lightCream
|
||||||
val md_theme_light_inverseSurface = Color(0xFF003547)
|
val md_theme_light_inverseSurface = darkBrown
|
||||||
val md_theme_light_inversePrimary = Color(0xFFFFB0C8)
|
val md_theme_light_inversePrimary = lightCream
|
||||||
val md_theme_light_surfaceTint = Color(0xFF984061)
|
val md_theme_light_surfaceTint = armyGreen
|
||||||
val md_theme_light_outlineVariant = Color(0xFFD5C2C6)
|
val md_theme_light_outlineVariant = tan
|
||||||
val md_theme_light_scrim = Color(0xFF000000)
|
val md_theme_light_scrim = Color(0xFF000000)
|
||||||
|
|
||||||
val md_theme_dark_primary = Color(0xFFFFB0C8)
|
// Material 3 Dark Theme Colors
|
||||||
val md_theme_dark_onPrimary = Color(0xFF5E1133)
|
val md_theme_dark_primary = tan
|
||||||
val md_theme_dark_primaryContainer = Color(0xFF7B2949)
|
val md_theme_dark_onPrimary = darkBrown
|
||||||
val md_theme_dark_onPrimaryContainer = Color(0xFFFFD9E2)
|
val md_theme_dark_primaryContainer = armyGreen
|
||||||
val md_theme_dark_secondary = Color(0xFFDEB7FF)
|
val md_theme_dark_onPrimaryContainer = lightCream
|
||||||
val md_theme_dark_onSecondary = Color(0xFF44196A)
|
val md_theme_dark_secondary = tan
|
||||||
val md_theme_dark_secondaryContainer = Color(0xFF5C3382)
|
val md_theme_dark_onSecondary = darkBrown
|
||||||
val md_theme_dark_onSecondaryContainer = Color(0xFFF1DBFF)
|
val md_theme_dark_secondaryContainer = armyGreen
|
||||||
val md_theme_dark_tertiary = Color(0xFFFFB1C7)
|
val md_theme_dark_onSecondaryContainer = lightCream
|
||||||
val md_theme_dark_onTertiary = Color(0xFF5E1132)
|
val md_theme_dark_tertiary = lightCream
|
||||||
val md_theme_dark_tertiaryContainer = Color(0xFF7B2948)
|
val md_theme_dark_onTertiary = armyGreen
|
||||||
val md_theme_dark_onTertiaryContainer = Color(0xFFFFD9E2)
|
val md_theme_dark_tertiaryContainer = darkBrown
|
||||||
|
val md_theme_dark_onTertiaryContainer = lightCream
|
||||||
val md_theme_dark_error = Color(0xFFFFB4AB)
|
val md_theme_dark_error = Color(0xFFFFB4AB)
|
||||||
val md_theme_dark_errorContainer = Color(0xFF93000A)
|
val md_theme_dark_errorContainer = Color(0xFF93000A)
|
||||||
val md_theme_dark_onError = Color(0xFF690005)
|
val md_theme_dark_onError = Color(0xFF690005)
|
||||||
val md_theme_dark_onErrorContainer = Color(0xFFFFDAD6)
|
val md_theme_dark_onErrorContainer = Color(0xFFFFDAD6)
|
||||||
val md_theme_dark_background = Color(0xFF001F2A)
|
val md_theme_dark_background = darkBrown
|
||||||
val md_theme_dark_onBackground = Color(0xFFBFE9FF)
|
val md_theme_dark_onBackground = lightCream
|
||||||
val md_theme_dark_surface = Color(0xFF001F2A)
|
val md_theme_dark_surface = darkBrown
|
||||||
val md_theme_dark_onSurface = Color(0xFFBFE9FF)
|
val md_theme_dark_onSurface = lightCream
|
||||||
val md_theme_dark_surfaceVariant = Color(0xFF514347)
|
val md_theme_dark_surfaceVariant = armyGreen
|
||||||
val md_theme_dark_onSurfaceVariant = Color(0xFFD5C2C6)
|
val md_theme_dark_onSurfaceVariant = lightCream
|
||||||
val md_theme_dark_outline = Color(0xFF9E8C90)
|
val md_theme_dark_outline = tan
|
||||||
val md_theme_dark_inverseOnSurface = Color(0xFF001F2A)
|
val md_theme_dark_inverseOnSurface = darkBrown
|
||||||
val md_theme_dark_inverseSurface = Color(0xFFBFE9FF)
|
val md_theme_dark_inverseSurface = lightCream
|
||||||
val md_theme_dark_inversePrimary = Color(0xFF984061)
|
val md_theme_dark_inversePrimary = armyGreen
|
||||||
val md_theme_dark_surfaceTint = Color(0xFFFFB0C8)
|
val md_theme_dark_surfaceTint = tan
|
||||||
val md_theme_dark_outlineVariant = Color(0xFF514347)
|
val md_theme_dark_outlineVariant = armyGreen
|
||||||
val md_theme_dark_scrim = Color(0xFF000000)
|
val md_theme_dark_scrim = Color(0xFF000000)
|
||||||
|
|||||||
@ -1,25 +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.
|
|
||||||
-->
|
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">BMI Calculator</string>
|
<string name="app_name">BMI Calculator</string>
|
||||||
<string name="calculate_tip">Calculate BMI</string>
|
<string name="calculate_tip">BMI Calculator</string>
|
||||||
<string name="height">Tinggi Badan</string>
|
<string name="height">Tinggi Badan (cm)</string>
|
||||||
<string name="weight">Berat Badan</string>
|
<string name="weight">Berat Badan (kg)</string>
|
||||||
<string name="use_usc">Gunakan Unit USC (lbs/in)?</string>
|
<string name="age">Umur</string>
|
||||||
<string name="bmi_calculation">BMI Anda: %s</string>
|
|
||||||
<string name="bmi_category">Kategori: %s</string>
|
<!-- Result Screen -->
|
||||||
|
<string name="result_title">Result</string>
|
||||||
|
<string name="bmi_value_category">BMI = %.1f kg/m² (%s)</string>
|
||||||
|
<string name="healthy_bmi_range">Healthy BMI range: 18.5 kg/m² - 25 kg/m²</string>
|
||||||
|
<string name="healthy_weight_for_height">Healthy weight for your height: %.1f kg - %.1f kg</string>
|
||||||
|
<string name="bmi_prime">BMI Prime: %.2f</string>
|
||||||
|
<string name="ponderal_index">Ponderal Index: %.1f kg/m³</string>
|
||||||
|
|
||||||
|
<!-- BMI Categories -->
|
||||||
|
<string name="underweight">Underweight</string>
|
||||||
|
<string name="normal">Normal</string>
|
||||||
|
<string name="overweight">Overweight</string>
|
||||||
|
<string name="obesity">Obesity</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user