Completed Tutorial :)
This commit is contained in:
parent
4b6bf04748
commit
22922b27de
|
@ -15,39 +15,59 @@
|
|||
*/
|
||||
package com.example.cupcake
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.dimensionResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import com.example.cupcake.data.DataSource
|
||||
import com.example.cupcake.ui.OrderSummaryScreen
|
||||
import com.example.cupcake.ui.OrderViewModel
|
||||
import com.example.cupcake.ui.SelectOptionScreen
|
||||
import com.example.cupcake.ui.StartOrderScreen
|
||||
|
||||
|
||||
enum class CupcakeScreen(@StringRes val title: Int) {
|
||||
Start(title = R.string.app_name),
|
||||
Flavor(title = R.string.choose_flavor),
|
||||
Pickup(title = R.string.choose_pickup_date),
|
||||
Summary(title = R.string.order_summary)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Composable that displays the topBar and displays back button if back navigation is possible.
|
||||
*/
|
||||
@Composable
|
||||
fun CupcakeAppBar(
|
||||
currentScreen: CupcakeScreen,
|
||||
canNavigateBack: Boolean,
|
||||
navigateUp: () -> Unit,
|
||||
navigateUp: () -> Unit = {},
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
TopAppBar(
|
||||
title = { Text(stringResource(id = R.string.app_name)) },
|
||||
colors = TopAppBarDefaults.mediumTopAppBarColors(
|
||||
containerColor = MaterialTheme.colorScheme.primaryContainer
|
||||
),
|
||||
title = { Text(stringResource(currentScreen.title)) },
|
||||
modifier = modifier,
|
||||
navigationIcon = {
|
||||
if (canNavigateBack) {
|
||||
|
@ -60,6 +80,7 @@ fun CupcakeAppBar(
|
|||
}
|
||||
}
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
@ -67,16 +88,111 @@ fun CupcakeApp(
|
|||
viewModel: OrderViewModel = viewModel(),
|
||||
navController: NavHostController = rememberNavController()
|
||||
) {
|
||||
val backStackEntry by navController.currentBackStackEntryAsState()
|
||||
val currentScreen = CupcakeScreen.valueOf(
|
||||
backStackEntry?.destination?.route ?: CupcakeScreen.Start.name
|
||||
)
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
CupcakeAppBar(
|
||||
canNavigateBack = false,
|
||||
navigateUp = { /* TODO: implement back navigation */ }
|
||||
currentScreen = currentScreen,
|
||||
canNavigateBack = navController.previousBackStackEntry != null,
|
||||
navigateUp = { navController.navigateUp() }
|
||||
)
|
||||
|
||||
}
|
||||
) { innerPadding ->
|
||||
val uiState by viewModel.uiState.collectAsState()
|
||||
|
||||
|
||||
NavHost(
|
||||
navController = navController,
|
||||
startDestination = CupcakeScreen.Start.name,
|
||||
modifier = Modifier.padding(innerPadding)
|
||||
) {
|
||||
composable(route = CupcakeScreen.Start.name) {
|
||||
StartOrderScreen(
|
||||
quantityOptions = DataSource.quantityOptions,
|
||||
onNextButtonClicked = {
|
||||
viewModel.setQuantity(it)
|
||||
navController.navigate(CupcakeScreen.Flavor.name)
|
||||
},
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(dimensionResource(R.dimen.padding_medium))
|
||||
)
|
||||
}
|
||||
|
||||
composable(route = CupcakeScreen.Flavor.name) {
|
||||
val context = LocalContext.current
|
||||
SelectOptionScreen(
|
||||
subtotal = uiState.price,
|
||||
onNextButtonClicked = { navController.navigate(CupcakeScreen.Pickup.name) },
|
||||
onCancelButtonClicked = {
|
||||
cancelOrderAndNavigateToStart(viewModel, navController)
|
||||
},
|
||||
options = DataSource.flavors.map { id -> context.resources.getString(id) },
|
||||
onSelectionChanged = { viewModel.setFlavor(it) },
|
||||
modifier = Modifier.fillMaxHeight()
|
||||
)
|
||||
}
|
||||
|
||||
composable(route = CupcakeScreen.Pickup.name) {
|
||||
SelectOptionScreen(
|
||||
subtotal = uiState.price,
|
||||
onNextButtonClicked = { navController.navigate(CupcakeScreen.Summary.name) },
|
||||
onCancelButtonClicked = {
|
||||
cancelOrderAndNavigateToStart(viewModel, navController)
|
||||
},
|
||||
options = uiState.pickupOptions,
|
||||
onSelectionChanged = { viewModel.setDate(it) },
|
||||
modifier = Modifier.fillMaxHeight()
|
||||
)
|
||||
}
|
||||
|
||||
composable(route = CupcakeScreen.Summary.name) {
|
||||
val context = LocalContext.current
|
||||
OrderSummaryScreen(
|
||||
orderUiState = uiState,
|
||||
onCancelButtonClicked = {
|
||||
cancelOrderAndNavigateToStart(viewModel, navController)
|
||||
},
|
||||
onSendButtonClicked = { subject: String, summary: String ->
|
||||
shareOrder(context, subject = subject, summary = summary)
|
||||
},
|
||||
|
||||
modifier = Modifier.fillMaxHeight()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun shareOrder(context: Context, subject: String, summary: String) {
|
||||
val intent = Intent(Intent.ACTION_SEND).apply {
|
||||
type = "text/plain"
|
||||
putExtra(Intent.EXTRA_SUBJECT, subject)
|
||||
putExtra(Intent.EXTRA_TEXT, summary)
|
||||
}
|
||||
|
||||
context.startActivity(
|
||||
Intent.createChooser(
|
||||
intent,
|
||||
context.getString(R.string.new_cupcake_order)
|
||||
)
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
|
||||
private fun cancelOrderAndNavigateToStart(
|
||||
viewModel: OrderViewModel,
|
||||
navController: NavHostController
|
||||
) {
|
||||
viewModel.resetOrder()
|
||||
navController.popBackStack(CupcakeScreen.Start.name, inclusive = false)
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,8 @@ fun SelectOptionScreen(
|
|||
subtotal: String,
|
||||
options: List<String>,
|
||||
onSelectionChanged: (String) -> Unit = {},
|
||||
onCancelButtonClicked: () -> Unit = {},
|
||||
onNextButtonClicked: () -> Unit = {},
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
var selectedValue by rememberSaveable { mutableStateOf("") }
|
||||
|
@ -105,7 +107,7 @@ fun SelectOptionScreen(
|
|||
) {
|
||||
OutlinedButton(
|
||||
modifier = Modifier.weight(1f),
|
||||
onClick = {}
|
||||
onClick = onCancelButtonClicked
|
||||
) {
|
||||
Text(stringResource(R.string.cancel))
|
||||
}
|
||||
|
@ -113,7 +115,7 @@ fun SelectOptionScreen(
|
|||
modifier = Modifier.weight(1f),
|
||||
// the button is enabled when the user makes a selection
|
||||
enabled = selectedValue.isNotEmpty(),
|
||||
onClick = {}
|
||||
onClick = onNextButtonClicked
|
||||
) {
|
||||
Text(stringResource(R.string.next))
|
||||
}
|
||||
|
|
|
@ -49,6 +49,8 @@ import com.example.cupcake.ui.theme.CupcakeTheme
|
|||
@Composable
|
||||
fun StartOrderScreen(
|
||||
quantityOptions: List<Pair<Int, Int>>,
|
||||
onNextButtonClicked: (Int) -> Unit,
|
||||
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Column(
|
||||
|
@ -83,7 +85,7 @@ fun StartOrderScreen(
|
|||
quantityOptions.forEach { item ->
|
||||
SelectQuantityButton(
|
||||
labelResourceId = item.first,
|
||||
onClick = {}
|
||||
onClick = { onNextButtonClicked(item.second) }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -114,9 +116,11 @@ fun StartOrderPreview() {
|
|||
CupcakeTheme {
|
||||
StartOrderScreen(
|
||||
quantityOptions = DataSource.quantityOptions,
|
||||
onNextButtonClicked = {},
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(dimensionResource(R.dimen.padding_medium))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,9 @@ import com.example.cupcake.ui.theme.CupcakeTheme
|
|||
@Composable
|
||||
fun OrderSummaryScreen(
|
||||
orderUiState: OrderUiState,
|
||||
onCancelButtonClicked: () -> Unit,
|
||||
onSendButtonClicked: (String, String) -> Unit,
|
||||
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val resources = LocalContext.current.resources
|
||||
|
@ -103,13 +106,13 @@ fun OrderSummaryScreen(
|
|||
) {
|
||||
Button(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
onClick = {}
|
||||
onClick = { onSendButtonClicked(newOrder, orderSummary) }
|
||||
) {
|
||||
Text(stringResource(R.string.send))
|
||||
}
|
||||
OutlinedButton(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
onClick = {}
|
||||
onClick = onCancelButtonClicked
|
||||
) {
|
||||
Text(stringResource(R.string.cancel))
|
||||
}
|
||||
|
@ -121,10 +124,13 @@ fun OrderSummaryScreen(
|
|||
@Preview
|
||||
@Composable
|
||||
fun OrderSummaryPreview() {
|
||||
CupcakeTheme {
|
||||
OrderSummaryScreen(
|
||||
orderUiState = OrderUiState(0, "Test", "Test", "$300.00"),
|
||||
modifier = Modifier.fillMaxHeight()
|
||||
)
|
||||
}
|
||||
CupcakeTheme {
|
||||
OrderSummaryScreen(
|
||||
orderUiState = OrderUiState(0, "Test", "Test", "$300.00"),
|
||||
onSendButtonClicked = { subject: String, summary: String -> },
|
||||
onCancelButtonClicked = {},
|
||||
modifier = Modifier.fillMaxHeight()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue