google-developer-training / basic-android-kotlin-compose-training-tip-calculator

Apache License 2.0
61 stars 97 forks source link

Calculate a custom tip: Android Basics with Compose #193

Closed gjmfs closed 7 months ago

gjmfs commented 7 months ago

URL of codelab

In which task and step of the codelab can this issue be found?

Describe the problem I declared Row function and I also declared Text and Switch functions inside of them. functional requirements are work verry well. but i have only issue about layout. will you tell me why is that Screenshot_20240404_221357

`/*

import android.graphics.Paint.Align import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.annotation.StringRes import androidx.compose.foundation.background 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.size 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.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.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource 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 com.example.tiptime.ui.theme.TipTimeTheme import java.text.NumberFormat

class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { enableEdgeToEdge() super.onCreate(savedInstanceState) setContent { TipTimeTheme { Surface( modifier = Modifier.fillMaxSize(), ) { TipTimeLayout() } } } } }

@Composable fun TipTimeLayout() { var amountInput by remember { mutableStateOf("") } var tipInput by remember { mutableStateOf("") } var roundUp by remember { mutableStateOf(false) } val tipPercent= tipInput.toDoubleOrNull()?:0.00 val amount = amountInput.toDoubleOrNull() ?: 0.0 val tip = calculateTip(amount,tipPercent,roundUp)

Column(
    modifier = Modifier
        .statusBarsPadding()
        .padding(horizontal = 40.dp)
        .verticalScroll(rememberScrollState())
        .safeDrawingPadding(),
    horizontalAlignment = Alignment.CenterHorizontally,
    verticalArrangement = Arrangement.Center
) {
    Text(
        text = stringResource(R.string.calculate_tip),
        modifier = Modifier
            .padding(bottom = 16.dp, top = 40.dp)
            .align(alignment = Alignment.Start)
    )
    EditNumberField(
        label1 = R.string.bill_amount,
        keyboardOptions = KeyboardOptions.Default.copy(
            keyboardType = KeyboardType.Number,
            imeAction = ImeAction.Next
        ),
        value = amountInput,
        onValueChanged = { amountInput = it },
        modifier = Modifier
            .padding(bottom = 32.dp)
            .fillMaxWidth()
    )
    EditNumberField(label1 = R.string.how_was_the_service,
        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 = stringResource(R.string.tip_amount, tip),
        style = MaterialTheme.typography.displaySmall
    )
    Spacer(modifier = Modifier.height(150.dp))
}

}

@Composable fun EditNumberField( @StringRes label1:Int, value: String, onValueChanged: (String) -> Unit, keyboardOptions : KeyboardOptions, modifier: Modifier ) { TextField( value = value, singleLine = true, modifier = modifier, onValueChange = onValueChanged, label = { Text(stringResource(label1)) }, keyboardOptions = keyboardOptions ) }

@Composable fun RoundTheTipRow( roundUp:Boolean, onRoundUpChanged:(Boolean)->Unit, modifier: Modifier=Modifier ){ Row( modifier= modifier .size(48.dp) .fillMaxWidth(), //verticalAlignment = Alignment.CenterVertically ) { Text( text = stringResource(id = R.string.round_up_tip), ) Switch( checked = roundUp, onCheckedChange = onRoundUpChanged, modifier= modifier .fillMaxWidth() .wrapContentWidth(Alignment.End) ) }

}

/**

@Preview(showBackground = true) @Composable fun TipTimeLayoutPreview() { TipTimeTheme { TipTimeLayout() } }

`

Steps to reproduce?

  1. Go to...
  2. Click on...
  3. See error...

Versions Android Studio version: API version of the emulator:

Additional information Include screenshots if they would be useful in clarifying the problem.

gjmfs commented 7 months ago

I figure out the issue. you can simply replace this code in your file it'll solve that bug

@Composable fun RoundTheTipRow( roundUp:Boolean, onRoundUpChanged:(Boolean)->Unit, modifier: Modifier=Modifier ){ Row( horizontalArrangement = Arrangement.SpaceBetween, modifier= modifier .fillMaxWidth() .size(48.dp) )

android-dev-lxl commented 7 months ago

@gjmfs Glad to know you resolved the issue, the the order of modifiers matters in Jetpack Compose. It can significantly affect the final appearance and behavior of your UI elements.

Here's a breakdown of how modifier order works:

Modifiers are applied left to right during the layout phase. This means modifiers that affect the size and placement of the element, like size or padding, are applied first. These modifiers determine the constraints for the element. After layout, modifiers are applied right to left during the drawing phase. Modifiers that affect the visual appearance without changing size or position, like clip or background, are applied in this stage. Understanding this order is crucial to achieve the desired outcome. For instance:

Adding padding after setting the size will create padding within the specified size. Conversely, adding size after padding will set the size considering the padding applied earlier.