Merge pull request #70 from google-developer-training/starter-e2e

Implement edge-to-edge on branch starter
This commit is contained in:
the-scrambler 2024-01-22 21:55:45 -08:00 committed by GitHub
commit 4b6bf04748
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 65 additions and 61 deletions

View File

@ -5,15 +5,12 @@ This app contains an order flow for cupcakes with options for quantity, flavor,
The order details get displayed on an order summary screen and can be shared to another app to
send the order.
TODO
Pre-requisites
--------------
* Experience with Kotlin syntax.
* How to create and run a project in Android Studio.
* How to create composable functions
* TODO
Getting Started

View File

@ -20,12 +20,12 @@ plugins {
android {
namespace = "com.example.cupcake"
compileSdk = 33
compileSdk = 34
defaultConfig {
applicationId = "com.example.cupcake"
minSdk = 24
targetSdk = 33
targetSdk = 34
versionCode = 1
versionName = "1.0"
@ -56,7 +56,7 @@ android {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.4.7"
kotlinCompilerExtensionVersion = "1.5.3"
}
packaging {
resources {
@ -67,20 +67,20 @@ android {
dependencies {
implementation(platform("androidx.compose:compose-bom:2023.05.01"))
implementation("androidx.activity:activity-compose:1.7.2")
implementation(platform("androidx.compose:compose-bom:2023.10.01"))
implementation("androidx.activity:activity-compose:1.8.0")
implementation("androidx.compose.material3:material3")
implementation("androidx.compose.runtime:runtime")
implementation("androidx.compose.runtime:runtime-livedata")
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-graphics")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.core:core-ktx:1.10.1")
implementation("androidx.core:core-ktx:1.12.0")
implementation("androidx.lifecycle:lifecycle-livedata-ktx:${rootProject.extra["lifecycle_version"]}")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:${rootProject.extra["lifecycle_version"]}")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:${rootProject.extra["lifecycle_version"]}")
implementation("androidx.lifecycle:lifecycle-viewmodel-savedstate:${rootProject.extra["lifecycle_version"]}")
implementation("androidx.navigation:navigation-compose:2.5.3")
implementation("androidx.navigation:navigation-compose:2.7.4")
debugImplementation("androidx.compose.ui:ui-test-manifest")
debugImplementation("androidx.compose.ui:ui-tooling")

View File

@ -18,13 +18,13 @@ package com.example.cupcake
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.core.view.WindowCompat
import androidx.activity.enableEdgeToEdge
import com.example.cupcake.ui.theme.CupcakeTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge()
super.onCreate(savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(window, false)
setContent {
CupcakeTheme {
CupcakeApp()

View File

@ -39,6 +39,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import com.example.cupcake.R
import com.example.cupcake.ui.components.FormattedPriceLabel
import com.example.cupcake.ui.theme.CupcakeTheme
/**
* Composable that displays the list of items as [RadioButton] options,
@ -52,14 +53,14 @@ fun SelectOptionScreen(
options: List<String>,
onSelectionChanged: (String) -> Unit = {},
modifier: Modifier = Modifier
){
) {
var selectedValue by rememberSaveable { mutableStateOf("") }
Column(
modifier = modifier,
verticalArrangement = Arrangement.SpaceBetween
) {
Column(modifier = Modifier.padding(dimensionResource(R.dimen.padding_medium))){
Column(modifier = Modifier.padding(dimensionResource(R.dimen.padding_medium))) {
options.forEach { item ->
Row(
modifier = Modifier.selectable(
@ -70,7 +71,7 @@ fun SelectOptionScreen(
}
),
verticalAlignment = Alignment.CenterVertically
){
) {
RadioButton(
selected = selectedValue == item,
onClick = {
@ -98,12 +99,14 @@ fun SelectOptionScreen(
Row(
modifier = Modifier
.fillMaxWidth()
.padding(dimensionResource(R.dimen.padding_medium))
.weight(1f, false),
.padding(dimensionResource(R.dimen.padding_medium)),
horizontalArrangement = Arrangement.spacedBy(dimensionResource(R.dimen.padding_medium)),
verticalAlignment = Alignment.Bottom
){
OutlinedButton(modifier = Modifier.weight(1f), onClick = {}) {
) {
OutlinedButton(
modifier = Modifier.weight(1f),
onClick = {}
) {
Text(stringResource(R.string.cancel))
}
Button(
@ -116,15 +119,16 @@ fun SelectOptionScreen(
}
}
}
}
@Preview
@Composable
fun SelectOptionPreview(){
SelectOptionScreen(
subtotal = "299.99",
options = listOf("Option 1", "Option 2", "Option 3", "Option 4"),
modifier = Modifier.fillMaxHeight()
)
fun SelectOptionPreview() {
CupcakeTheme {
SelectOptionScreen(
subtotal = "299.99",
options = listOf("Option 1", "Option 2", "Option 3", "Option 4"),
modifier = Modifier.fillMaxHeight()
)
}
}

View File

@ -19,7 +19,6 @@ import androidx.annotation.StringRes
import androidx.compose.foundation.Image
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
@ -40,6 +39,7 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.example.cupcake.R
import com.example.cupcake.data.DataSource
import com.example.cupcake.ui.theme.CupcakeTheme
/**
* Composable that allows the user to select the desired cupcake quantity and expects
@ -50,7 +50,7 @@ import com.example.cupcake.data.DataSource
fun StartOrderScreen(
quantityOptions: List<Pair<Int, Int>>,
modifier: Modifier = Modifier
){
) {
Column(
modifier = modifier,
verticalArrangement = Arrangement.SpaceBetween
@ -73,20 +73,18 @@ fun StartOrderScreen(
)
Spacer(modifier = Modifier.height(dimensionResource(R.dimen.padding_small)))
}
Row(modifier = Modifier.weight(1f, false)) {
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(
dimensionResource(id = R.dimen.padding_medium)
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(
dimensionResource(id = R.dimen.padding_medium)
)
) {
quantityOptions.forEach { item ->
SelectQuantityButton(
labelResourceId = item.first,
onClick = {}
)
) {
quantityOptions.forEach { item ->
SelectQuantityButton(
labelResourceId = item.first,
onClick = {}
)
}
}
}
}
@ -101,7 +99,7 @@ fun SelectQuantityButton(
@StringRes labelResourceId: Int,
onClick: () -> Unit,
modifier: Modifier = Modifier
){
) {
Button(
onClick = onClick,
modifier = modifier.widthIn(min = 250.dp)
@ -112,9 +110,13 @@ fun SelectQuantityButton(
@Preview
@Composable
fun StartOrderPreview(){
StartOrderScreen(
quantityOptions = DataSource.quantityOptions,
modifier = Modifier.fillMaxSize().padding(dimensionResource(R.dimen.padding_medium))
)
fun StartOrderPreview() {
CupcakeTheme {
StartOrderScreen(
quantityOptions = DataSource.quantityOptions,
modifier = Modifier
.fillMaxSize()
.padding(dimensionResource(R.dimen.padding_medium))
)
}
}

View File

@ -38,6 +38,7 @@ import androidx.compose.ui.tooling.preview.Preview
import com.example.cupcake.R
import com.example.cupcake.data.OrderUiState
import com.example.cupcake.ui.components.FormattedPriceLabel
import com.example.cupcake.ui.theme.CupcakeTheme
/**
* This composable expects [orderUiState] that represents the order state, [onCancelButtonClicked]
@ -48,7 +49,7 @@ import com.example.cupcake.ui.components.FormattedPriceLabel
fun OrderSummaryScreen(
orderUiState: OrderUiState,
modifier: Modifier = Modifier
){
) {
val resources = LocalContext.current.resources
val numberOfCupcakes = resources.getQuantityString(
@ -95,9 +96,7 @@ fun OrderSummaryScreen(
)
}
Row(
modifier = Modifier
.weight(1f, false)
.padding(dimensionResource(R.dimen.padding_medium))
modifier = Modifier.padding(dimensionResource(R.dimen.padding_medium))
) {
Column(
verticalArrangement = Arrangement.spacedBy(dimensionResource(R.dimen.padding_small))
@ -121,9 +120,11 @@ fun OrderSummaryScreen(
@Preview
@Composable
fun OrderSummaryPreview(){
OrderSummaryScreen(
orderUiState = OrderUiState(0, "Test", "Test", "$300.00"),
modifier = Modifier.fillMaxHeight()
)
fun OrderSummaryPreview() {
CupcakeTheme {
OrderSummaryScreen(
orderUiState = OrderUiState(0, "Test", "Test", "$300.00"),
modifier = Modifier.fillMaxHeight()
)
}
}

View File

@ -16,11 +16,11 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
extra.apply {
set("lifecycle_version", "2.6.1")
set("lifecycle_version", "2.6.2")
}
}
plugins {
id("com.android.application") version "8.0.2" apply false
id("com.android.library") version "8.0.2" apply false
id("org.jetbrains.kotlin.android") version "1.8.21" apply false
id("com.android.application") version "8.1.2" apply false
id("com.android.library") version "8.1.2" apply false
id("org.jetbrains.kotlin.android") version "1.9.10" apply false
}

View File

@ -1,6 +1,6 @@
#Sun Mar 19 17:30:22 PDT 2023
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists