https://developer.android.com/courses/pathways/android-basics-compose-unit-2-pathway-3
This is a part of Android Basics with Compose course.
Optional video.
var input by remember { mutableStateOf("") }
… Tip = Gratuity (Trinkgeld in DE)
…
…
starter branchTextField to the TipTimeLayout in MainActivity…
State and MutableState types in Compose to make state in your app observable, or tracked, by Compose. The State type is immutable, so you can only read the value in it, while the MutableState type is mutable. You can use the mutableStateOf() function to create an observable MutableState. It receives an initial value as a parameter that is wrapped in a State object, which then makes its value observable.…
@Composable fun EditNumberField(modifier: Modifier = Modifier) { var amountInput by remember { mutableStateOf("") } TextField( value = amountInput, onValueChange = { amountInput = it }, modifier = modifier ) }
amountInput without referring to the MutableState's value property.…
…
@Composable fun EditNumberField(modifier: Modifier = Modifier) { var amountInput by remember { mutableStateOf("") } TextField( value = amountInput, onValueChange = { amountInput = it }, singleLine = true, label = { Text(stringResource(R.string.bill_amount)) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), modifier = modifier ) }
amountInput) will be moved from EditNumberField one level up ⇒ to the TipTimeLayout.@Composable fun TipTimeLayout() { var amountInput by remember { mutableStateOf("") } val amount = amountInput.toDoubleOrNull() ?: 0.0 val tip = calculateTip(amount) 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( value = amountInput, onValueChange = { amountInput = it }, modifier = Modifier .padding(bottom = 32.dp) .fillMaxWidth() ) Text( text = stringResource(R.string.tip_amount, tip), style = MaterialTheme.typography.displaySmall ) Spacer(modifier = Modifier.height(150.dp)) } } @Composable fun EditNumberField( value: String, onValueChange: (String) -> Unit, modifier: Modifier = Modifier ) { TextField( value = value, onValueChange = onValueChange, singleLine = true, label = { Text(stringResource(R.string.bill_amount)) }, keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number), modifier = modifier ) }
…
…
…
…
…
label parameter to the EditNumberField…
@StringRes annotation is a type-safe way to use string resources.…
…
keyboardOptions = KeyboardOptions.Default.copy( keyboardType = KeyboardType.Number, imeAction = ImeAction.Next ),
…
Switch( checked = roundUp, onCheckedChange = onRoundUpChanged, modifier = modifier .fillMaxWidth() .wrapContentWidth(Alignment.End), )
…
…
@Composable fun TipTimeLayout() { // ... Column( modifier = Modifier .padding(40.dp) .verticalScroll(rememberScrollState()), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { //... } }
…
TextField( value = value, leadingIcon = { Icon(painter = painterResource(id = leadingIcon), null) }, //... )
…
…
…
…
…
@VisibleForTesting annotation ……
Local tests directly test methods from the app code, so the methods to be tested must be available to the testing classes and methods. So:
private methods as internal@VisibleForTesting annotationThe following list of concepts apply to local and instrumentation tests:
assertTrue() assertion is commonly used in Android testing. …
src/androidTest/java …
…
Summary:
ComposeTestRule to launch the app with a test.…
…
…
…
…
…