From 5e7c81e0da4c799e5d92bae3ea1c7d69b68c1939 Mon Sep 17 00:00:00 2001 From: Magda Wojtowicz Date: Tue, 30 Jul 2024 21:06:57 +0200 Subject: [PATCH 01/11] Added a file with composable that displays details of one product. --- .../android/demo/ui/shop/ProductDetails.kt | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ProductDetails.kt diff --git a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ProductDetails.kt b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ProductDetails.kt new file mode 100644 index 000000000..27cf0fd2e --- /dev/null +++ b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ProductDetails.kt @@ -0,0 +1,90 @@ +package io.opentelemetry.android.demo.ui.shop + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.* +import androidx.compose.material3.* +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.asImageBitmap +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import io.opentelemetry.android.demo.clients.ImageLoader +import io.opentelemetry.android.demo.gothamFont +import io.opentelemetry.android.demo.model.PriceUsd +import io.opentelemetry.android.demo.model.Product +import io.opentelemetry.android.demo.theme.DemoAppTheme + +@Composable +fun ProductDetails(product:Product){ + val imageLoader = ImageLoader(LocalContext.current) + val sourceProductImage = imageLoader.load(product.picture) + + Column( + modifier = Modifier + .fillMaxSize() + .padding(16.dp) + ) { + Image( + bitmap = sourceProductImage.asImageBitmap(), + contentDescription = product.name, + modifier = Modifier + .fillMaxWidth() + .height(300.dp) + ) + Spacer(modifier = Modifier.height(16.dp)) + Text( + text = product.name, + fontFamily = gothamFont, + fontSize = 24.sp, + modifier = Modifier.fillMaxWidth(), + textAlign = TextAlign.Center + ) + Spacer(modifier = Modifier.height(16.dp)) + Text( + text = product.description, + color = Color.Gray, + textAlign = TextAlign.Justify, + fontFamily = gothamFont, + fontSize = 16.sp, + modifier = Modifier.fillMaxWidth() + ) + Spacer(modifier = Modifier.height(16.dp)) + Text( + text = "$${product.priceValue()}", + fontFamily = gothamFont, + fontSize = 24.sp, + modifier = Modifier.fillMaxWidth(), + textAlign = TextAlign.Center + ) + Spacer(modifier = Modifier.height(32.dp)) + Button( + onClick = { /* TODO: Handle add to cart */ }, + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp) + ) { + Text(text = "Add to Cart") + } + } +} + +@Preview(showBackground = true, widthDp = 320) +@Composable +fun ProductDetailsPreview() { + val price = PriceUsd("USD", 349, 950000000) + val categories = listOf("telescopes") + val product = Product("66VCHSJNUP", + "Starsense Explorer Refractor Telescope", + "The first telescope that uses your smartphone to analyze the night sky and calculate its position in real time. StarSense Explorer is ideal for beginners thanks to the app’s user-friendly interface and detailed tutorials. It’s like having your own personal tour guide of the night sky", + "StarsenseExplorer.jpg", + price, + categories) + DemoAppTheme { + ProductDetails(product) + } +} \ No newline at end of file From d636d6c3a0e94472406b10ad49992af44e388c54 Mon Sep 17 00:00:00 2001 From: Magda Wojtowicz Date: Tue, 30 Jul 2024 21:07:16 +0200 Subject: [PATCH 02/11] navigation to product details - not pretty but works --- demo-app/build.gradle.kts | 2 ++ .../android/demo/ui/shop/ProductCard.kt | 6 ++-- .../android/demo/ui/shop/ProductDetails.kt | 19 ++---------- .../android/demo/ui/shop/ProductList.kt | 5 ++-- .../android/demo/ui/shop/ShopFragment.kt | 30 +++++++++++++++++-- 5 files changed, 40 insertions(+), 22 deletions(-) diff --git a/demo-app/build.gradle.kts b/demo-app/build.gradle.kts index 75b3eeaca..c3d9d03a0 100644 --- a/demo-app/build.gradle.kts +++ b/demo-app/build.gradle.kts @@ -65,6 +65,8 @@ dependencies { implementation(libs.androidx.navigation.fragment.ktx) implementation(libs.androidx.navigation.ui.ktx) implementation(libs.opentelemetry.api.incubator) + val nav_version = "2.7.7" + implementation("androidx.navigation:navigation-compose:$nav_version") coreLibraryDesugaring(libs.desugarJdkLibs) diff --git a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ProductCard.kt b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ProductCard.kt index 0da990da4..10c19ddc7 100644 --- a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ProductCard.kt +++ b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ProductCard.kt @@ -24,13 +24,14 @@ import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.navigation.NavController import io.opentelemetry.android.demo.TAG import io.opentelemetry.android.demo.clients.ImageLoader import io.opentelemetry.android.demo.gothamFont import io.opentelemetry.android.demo.model.Product @Composable -fun ProductCard(product: Product) { +fun ProductCard(product: Product, navController: NavController) { val imageLoader = ImageLoader(LocalContext.current) val sourceProductImage = imageLoader.load(product.picture) Bitmap.createScaledBitmap(sourceProductImage, 120, 120, false) @@ -47,7 +48,8 @@ fun ProductCard(product: Product) { .wrapContentHeight() .padding(20.dp), onClick = { - Log.d(TAG, "TODO: Implement me!") + navController.navigate("prod-details/${product.id}") +// Log.d(TAG, "TODO: Implement me!") } ) { Row(modifier = Modifier.fillMaxSize().padding(20.dp)) { diff --git a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ProductDetails.kt b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ProductDetails.kt index 27cf0fd2e..3ddbcefb5 100644 --- a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ProductDetails.kt +++ b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ProductDetails.kt @@ -2,6 +2,8 @@ package io.opentelemetry.android.demo.ui.shop import androidx.compose.foundation.Image import androidx.compose.foundation.layout.* +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment @@ -28,6 +30,7 @@ fun ProductDetails(product:Product){ modifier = Modifier .fillMaxSize() .padding(16.dp) + .verticalScroll(rememberScrollState()) ) { Image( bitmap = sourceProductImage.asImageBitmap(), @@ -72,19 +75,3 @@ fun ProductDetails(product:Product){ } } } - -@Preview(showBackground = true, widthDp = 320) -@Composable -fun ProductDetailsPreview() { - val price = PriceUsd("USD", 349, 950000000) - val categories = listOf("telescopes") - val product = Product("66VCHSJNUP", - "Starsense Explorer Refractor Telescope", - "The first telescope that uses your smartphone to analyze the night sky and calculate its position in real time. StarSense Explorer is ideal for beginners thanks to the app’s user-friendly interface and detailed tutorials. It’s like having your own personal tour guide of the night sky", - "StarsenseExplorer.jpg", - price, - categories) - DemoAppTheme { - ProductDetails(product) - } -} \ No newline at end of file diff --git a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ProductList.kt b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ProductList.kt index 04de9d82e..48b2c77b6 100644 --- a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ProductList.kt +++ b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ProductList.kt @@ -9,14 +9,15 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.State import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp +import androidx.navigation.NavController import io.opentelemetry.android.demo.model.Product @Composable -fun ProductList(products: State>) { +fun ProductList(products: State>, navController: NavController) { LazyColumn(modifier = Modifier.fillMaxSize()) { items(products.value.size) { index -> Row() { - ProductCard(products.value[index]) + ProductCard(products.value[index], navController = navController) } } item { diff --git a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ShopFragment.kt b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ShopFragment.kt index b5ea4294c..15da46e38 100644 --- a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ShopFragment.kt +++ b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ShopFragment.kt @@ -17,6 +17,11 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.ui.Modifier import androidx.compose.ui.platform.ComposeView import androidx.fragment.app.Fragment +import androidx.navigation.NavType +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import androidx.navigation.compose.rememberNavController +import androidx.navigation.navArgument import io.opentelemetry.android.demo.clients.ProductCatalogClient import io.opentelemetry.android.demo.theme.DemoAppTheme @@ -34,17 +39,38 @@ class ShopFragment : Fragment() { return ComposeView(requireContext()).apply { setContent { + + val navController = rememberNavController() + DemoAppTheme { // A surface container using the 'background' color from the theme Surface( modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background, ) { - ProductList(productState) + NavHost(navController = navController, startDestination = "prod-list") { + composable("prod-list") { + ProductList( + products = productState, + navController = navController + ) + } + composable( + "prod-details/{productId}", + arguments = listOf(navArgument("productId") { + type = NavType.StringType + }) + ) { backStackEntry -> + val productId = backStackEntry.arguments?.getString("productId") + val product = products.find { it.id == productId } + product?.let { + ProductDetails(product = it) + } + } + } } } } } } - } From 6a7bbd28a633cb8b04ad8aa391deeb9f8320d6b0 Mon Sep 17 00:00:00 2001 From: Magda Wojtowicz Date: Tue, 30 Jul 2024 21:07:27 +0200 Subject: [PATCH 03/11] compose navigation stuff added to build gradle --- demo-app/build.gradle.kts | 6 ++++-- demo-app/gradle/libs.versions.toml | 6 ++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/demo-app/build.gradle.kts b/demo-app/build.gradle.kts index c3d9d03a0..dc2a3973b 100644 --- a/demo-app/build.gradle.kts +++ b/demo-app/build.gradle.kts @@ -65,8 +65,10 @@ dependencies { implementation(libs.androidx.navigation.fragment.ktx) implementation(libs.androidx.navigation.ui.ktx) implementation(libs.opentelemetry.api.incubator) - val nav_version = "2.7.7" - implementation("androidx.navigation:navigation-compose:$nav_version") + implementation(libs.androidx.navigation.compose) + +// val nav_version = "2.7.7" +// implementation("androidx.navigation:navigation-compose:$nav_version") coreLibraryDesugaring(libs.desugarJdkLibs) diff --git a/demo-app/gradle/libs.versions.toml b/demo-app/gradle/libs.versions.toml index ea8041f42..ab03437cf 100644 --- a/demo-app/gradle/libs.versions.toml +++ b/demo-app/gradle/libs.versions.toml @@ -4,6 +4,7 @@ opentelemetry-alpha = "1.39.0-alpha" junit = "5.10.3" spotless = "6.25.0" kotlin = "2.0.0" +navigation-compose = "2.7.7" [libraries] androidx-appcompat = "androidx.appcompat:appcompat:1.7.0" @@ -37,6 +38,11 @@ androidx-lifecycle-livedata-ktx = { group = "androidx.lifecycle", name = "lifecy androidx-lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version = "2.8.4" } androidx-navigation-fragment-ktx = { group = "androidx.navigation", name = "navigation-fragment-ktx", version = "2.7.7" } androidx-navigation-ui-ktx = { group = "androidx.navigation", name = "navigation-ui-ktx", version = "2.7.7" } +androidx-lifecycle-livedata-ktx = { group = "androidx.lifecycle", name = "lifecycle-livedata-ktx", version = "2.8.3" } +androidx-lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version = "2.8.3" } +androidx-navigation-fragment-ktx = { group = "androidx.navigation", name = "navigation-fragment-ktx", version.ref = "navigation-compose" } +androidx-navigation-ui-ktx = { group = "androidx.navigation", name = "navigation-ui-ktx", version.ref = "navigation-compose" } +androidx-navigation-compose = {group = "androidx.navigation", name = "navigation-compose", version.ref = "navigation-compose"} [bundles] junit = ["junit-jupiter-api", "junit-jupiter-engine", "junit-vintage-engine"] From 37aa2c75959b25dba7f3f1bbc25a07d776e2b725 Mon Sep 17 00:00:00 2001 From: Magda Wojtowicz Date: Tue, 30 Jul 2024 21:07:34 +0200 Subject: [PATCH 04/11] started refactoring to get rid of fragments and do only compose navigation --- demo-app/build.gradle.kts | 3 - demo-app/src/main/AndroidManifest.xml | 2 +- .../android/demo/AstronomyShopActivity.kt | 50 ------- .../android/demo/MainActivity.kt | 1 + .../demo/ui/shop/AstronomyShopActivity.kt | 90 ++++++++++++ .../android/demo/ui/shop/Navigation.kt | 132 ++++++++++++++++++ .../android/demo/ui/shop/ShopFragment.kt | 97 ++++++------- .../android/demo/ui/shop/cart/Cart.kt | 63 +++++++++ .../ui/shop/{ => products}/ProductCard.kt | 8 +- .../ui/shop/{ => products}/ProductDetails.kt | 6 +- .../ui/shop/{ => products}/ProductList.kt | 9 +- 11 files changed, 343 insertions(+), 118 deletions(-) delete mode 100644 demo-app/src/main/java/io/opentelemetry/android/demo/AstronomyShopActivity.kt create mode 100644 demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/AstronomyShopActivity.kt create mode 100644 demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/Navigation.kt create mode 100644 demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/cart/Cart.kt rename demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/{ => products}/ProductCard.kt (90%) rename demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/{ => products}/ProductDetails.kt (90%) rename demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/{ => products}/ProductList.kt (69%) diff --git a/demo-app/build.gradle.kts b/demo-app/build.gradle.kts index dc2a3973b..1f2f1f20e 100644 --- a/demo-app/build.gradle.kts +++ b/demo-app/build.gradle.kts @@ -67,9 +67,6 @@ dependencies { implementation(libs.opentelemetry.api.incubator) implementation(libs.androidx.navigation.compose) -// val nav_version = "2.7.7" -// implementation("androidx.navigation:navigation-compose:$nav_version") - coreLibraryDesugaring(libs.desugarJdkLibs) implementation("io.opentelemetry.android:android-agent") //parent dir diff --git a/demo-app/src/main/AndroidManifest.xml b/demo-app/src/main/AndroidManifest.xml index c04a07e76..1046456dd 100644 --- a/demo-app/src/main/AndroidManifest.xml +++ b/demo-app/src/main/AndroidManifest.xml @@ -18,7 +18,7 @@ android:usesCleartextTraffic="true" tools:targetApi="31"> diff --git a/demo-app/src/main/java/io/opentelemetry/android/demo/AstronomyShopActivity.kt b/demo-app/src/main/java/io/opentelemetry/android/demo/AstronomyShopActivity.kt deleted file mode 100644 index f031cb71b..000000000 --- a/demo-app/src/main/java/io/opentelemetry/android/demo/AstronomyShopActivity.kt +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.android.demo - -import android.content.Intent -import android.os.Bundle -import android.util.Log -import android.view.MenuItem -import androidx.appcompat.app.AppCompatActivity -import androidx.navigation.findNavController -import androidx.navigation.ui.AppBarConfiguration -import androidx.navigation.ui.setupActionBarWithNavController -import androidx.navigation.ui.setupWithNavController -import com.google.android.material.bottomnavigation.BottomNavigationView -import io.opentelemetry.android.demo.databinding.ActivityAstronomyShopBinding - -class AstronomyShopActivity : AppCompatActivity() { - private lateinit var binding: ActivityAstronomyShopBinding - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - binding = ActivityAstronomyShopBinding.inflate(layoutInflater) - setContentView(binding.root) - - val navView: BottomNavigationView = binding.navView - - val navController = findNavController(R.id.nav_host_fragment_activity_astronomy_shop) - // Passing each menu ID as a set of Ids because each - // menu should be considered as top level destinations. - val appBarConfiguration = - AppBarConfiguration( - setOf( - R.id.navigation_home, - R.id.navigation_dashboard, - R.id.navigation_cart, - ), - ) - setupActionBarWithNavController(navController, appBarConfiguration) - navView.setupWithNavController(navController) - } - - fun onExitToMainClicked(item: MenuItem) { - Log.d(TAG, "Exiting shop back to main activity") - startActivity(Intent(this@AstronomyShopActivity, MainActivity::class.java)) - } -} diff --git a/demo-app/src/main/java/io/opentelemetry/android/demo/MainActivity.kt b/demo-app/src/main/java/io/opentelemetry/android/demo/MainActivity.kt index 96ee2730d..6e5c2a36e 100644 --- a/demo-app/src/main/java/io/opentelemetry/android/demo/MainActivity.kt +++ b/demo-app/src/main/java/io/opentelemetry/android/demo/MainActivity.kt @@ -29,6 +29,7 @@ import androidx.compose.ui.text.withStyle import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import io.opentelemetry.android.demo.theme.DemoAppTheme +import io.opentelemetry.android.demo.ui.shop.AstronomyShopActivity class MainActivity : ComponentActivity() { private val viewModel by viewModels() diff --git a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/AstronomyShopActivity.kt b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/AstronomyShopActivity.kt new file mode 100644 index 000000000..42ecd39dd --- /dev/null +++ b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/AstronomyShopActivity.kt @@ -0,0 +1,90 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.android.demo.ui.shop + +import android.app.Activity +import android.content.Intent +import android.os.Bundle +import androidx.activity.compose.setContent +import androidx.appcompat.app.AppCompatActivity +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import io.opentelemetry.android.demo.MainActivity +import io.opentelemetry.android.demo.clients.ProductCatalogClient +import io.opentelemetry.android.demo.theme.DemoAppTheme +import io.opentelemetry.android.demo.ui.shop.cart.CartScreen +import io.opentelemetry.android.demo.ui.shop.products.ProductDetails +import io.opentelemetry.android.demo.ui.shop.products.ProductList + + +class AstronomyShopActivity : AppCompatActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + AstronomyShopScreen() + } + } +} + +@Composable +fun AstronomyShopScreen(){ + val productsClient = ProductCatalogClient(LocalContext.current) + val products by remember { mutableStateOf(productsClient.get()) } + + DemoAppTheme { + Surface( + modifier = Modifier.fillMaxSize(), + color = MaterialTheme.colorScheme.background + ) { + val astronomyShopNavController = rememberAstronomyShopNavController() + Scaffold( + bottomBar = { + BottomNavigationBar(navController = astronomyShopNavController.navController, + onExitClicked = { +// TODO + } + ) + + } + ) { innerPadding -> + NavHost( + navController = astronomyShopNavController.navController, + startDestination = "prod-list", + Modifier.padding(innerPadding) // Ensure proper padding with Scaffold + ) { + composable("prod-list") { + ProductList( + products = products + ) + } + composable(BottomNavItem.List.route) { + ProductList( + products = products + ) + } + composable(BottomNavItem.Cart.route) { + CartScreen() + } + } + } + } + } +} + + + diff --git a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/Navigation.kt b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/Navigation.kt new file mode 100644 index 000000000..cd40dc501 --- /dev/null +++ b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/Navigation.kt @@ -0,0 +1,132 @@ +package io.opentelemetry.android.demo.ui.shop + +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.automirrored.filled.ExitToApp +import androidx.compose.material.icons.automirrored.filled.List +import androidx.compose.material.icons.filled.ExitToApp +import androidx.compose.material.icons.filled.List +import androidx.compose.material.icons.filled.ShoppingCart +import androidx.compose.material3.Icon +import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable +import androidx.compose.runtime.remember +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.lifecycle.Lifecycle +import androidx.navigation.NavBackStackEntry +import androidx.navigation.NavController +import androidx.navigation.NavDestination +import androidx.navigation.NavGraph +import androidx.navigation.NavHostController +import androidx.navigation.compose.rememberNavController +import androidx.compose.material3.* +import androidx.compose.runtime.getValue +import androidx.navigation.compose.currentBackStackEntryAsState + +sealed class BottomNavItem(val route: String, val icon: ImageVector, val label: String) { + object Exit : BottomNavItem("home", Icons.AutoMirrored.Filled.ExitToApp, "Exit") + object List : BottomNavItem("prod-list", Icons.AutoMirrored.Filled.List, "List") + object Cart : BottomNavItem("cart", Icons.Filled.ShoppingCart, "Cart") +} + +@Composable +fun BottomNavigationBar(navController: NavController, onExitClicked: () -> Unit) { + NavigationBar { + val navBackStackEntry by navController.currentBackStackEntryAsState() + val currentRoute = navBackStackEntry?.destination?.route + + + val items = listOf( + BottomNavItem.Exit, + BottomNavItem.List, + BottomNavItem.Cart + ) + + items.forEach { item -> + NavigationBarItem( + selected = currentRoute == item.route, + onClick = { + if (item.route == BottomNavItem.Exit.route) { + onExitClicked() + } else { + navController.navigate(item.route) { + popUpTo(navController.graph.startDestinationId) + launchSingleTop = true + } + } + }, + icon = { Icon(item.icon, contentDescription = item.label) }, + label = { Text(item.label) } + ) + } + } +} + +object MainDestinations { + const val HOME_ROUTE = "prod-list" + const val PRODUCT_DETAIL_ROUTE = "product" + const val PRODUCT_ID_KEY = "productId" +} + +@Composable +fun rememberAstronomyShopNavController(navController: NavHostController = rememberNavController()) +: AstronomyShopNavController = remember(navController) +{ + AstronomyShopNavController(navController) +} + +/** + * Responsible for holding UI Navigation logic. + */ +@Stable +class AstronomyShopNavController( + val navController: NavHostController, +) { + val currentRoute: String? + get() = navController.currentDestination?.route + + fun upPress() { + navController.navigateUp() + } + + fun navigateToBottomBarRoute(route: String) { + if (route != currentRoute) { + navController.navigate(route) { + launchSingleTop = true + restoreState = true + // Pop up backstack to the first destination and save state. This makes going back + // to the start destination when pressing back in any other bottom tab. + popUpTo(findStartDestination(navController.graph).id) { + saveState = true + } + } + } + } + fun navigateToProductDetail(productId: String, from: NavBackStackEntry) { + // In order to discard duplicated navigation events, we check the Lifecycle + if (from.lifecycleIsResumed()) { + navController.navigate("${MainDestinations.PRODUCT_DETAIL_ROUTE}/$productId") + } + } +} + + +/** + * If the lifecycle is not resumed it means this NavBackStackEntry already processed a nav event. + * + * This is used to de-duplicate navigation events. + */ +private fun NavBackStackEntry.lifecycleIsResumed() = + this.lifecycle.currentState == Lifecycle.State.RESUMED + +private val NavGraph.startDestination: NavDestination? + get() = findNode(startDestinationId) + +/** + * Copied from similar function in NavigationUI.kt + * + * https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:navigation/navigation-ui/src/main/java/androidx/navigation/ui/NavigationUI.kt + */ +private tailrec fun findStartDestination(graph: NavDestination): NavDestination { + return if (graph is NavGraph) findStartDestination(graph.startDestination!!) else graph +} + diff --git a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ShopFragment.kt b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ShopFragment.kt index 15da46e38..d99883ab6 100644 --- a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ShopFragment.kt +++ b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ShopFragment.kt @@ -12,7 +12,6 @@ import android.view.ViewGroup import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface -import androidx.compose.material3.Text import androidx.compose.runtime.mutableStateOf import androidx.compose.ui.Modifier import androidx.compose.ui.platform.ComposeView @@ -24,53 +23,55 @@ import androidx.navigation.compose.rememberNavController import androidx.navigation.navArgument import io.opentelemetry.android.demo.clients.ProductCatalogClient import io.opentelemetry.android.demo.theme.DemoAppTheme +import io.opentelemetry.android.demo.ui.shop.products.ProductDetails +import io.opentelemetry.android.demo.ui.shop.products.ProductList class ShopFragment : Fragment() { - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle?, - ): View { - - val productsClient = ProductCatalogClient(requireContext()) - val products = productsClient.get() - val productState = mutableStateOf(products) - - return ComposeView(requireContext()).apply { - setContent { - - val navController = rememberNavController() - - DemoAppTheme { - // A surface container using the 'background' color from the theme - Surface( - modifier = Modifier.fillMaxSize(), - color = MaterialTheme.colorScheme.background, - ) { - NavHost(navController = navController, startDestination = "prod-list") { - composable("prod-list") { - ProductList( - products = productState, - navController = navController - ) - } - composable( - "prod-details/{productId}", - arguments = listOf(navArgument("productId") { - type = NavType.StringType - }) - ) { backStackEntry -> - val productId = backStackEntry.arguments?.getString("productId") - val product = products.find { it.id == productId } - product?.let { - ProductDetails(product = it) - } - } - } - } - } - } - } - } +// +// override fun onCreateView( +// inflater: LayoutInflater, +// container: ViewGroup?, +// savedInstanceState: Bundle?, +// ): View { +// +// val productsClient = ProductCatalogClient(requireContext()) +// val products = productsClient.get() +// val productState = mutableStateOf(products) +// +// return ComposeView(requireContext()).apply { +// setContent { +// +// val navController = rememberNavController() +// +// DemoAppTheme { +// // A surface container using the 'background' color from the theme +// Surface( +// modifier = Modifier.fillMaxSize(), +// color = MaterialTheme.colorScheme.background, +// ) { +// NavHost(navController = navController, startDestination = "prod-list") { +// composable("prod-list") { +// ProductList( +// products = productState, +// navController = navController +// ) +// } +// composable( +// "prod-details/{productId}", +// arguments = listOf(navArgument("productId") { +// type = NavType.StringType +// }) +// ) { backStackEntry -> +// val productId = backStackEntry.arguments?.getString("productId") +// val product = products.find { it.id == productId } +// product?.let { +// ProductDetails(product = it) +// } +// } +// } +// } +// } +// } +// } +// } } diff --git a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/cart/Cart.kt b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/cart/Cart.kt new file mode 100644 index 000000000..4015577ba --- /dev/null +++ b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/cart/Cart.kt @@ -0,0 +1,63 @@ +package io.opentelemetry.android.demo.ui.shop.cart + +import androidx.compose.material3.Scaffold +import androidx.compose.runtime.Composable +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.material3.Button +import androidx.compose.material3.Text +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import io.opentelemetry.android.demo.model.Product + + +@Composable +fun CartScreen() { +// val products + Scaffold( + content = { innerPadding -> + Column( + modifier = Modifier + .fillMaxSize() + .padding(innerPadding), + verticalArrangement = Arrangement.SpaceBetween + ) { + LazyColumn( + modifier = Modifier.weight(1f) + ) { +// this.items(products) { product -> CartItem(product) } + } +// CheckoutButton(totalPrice = products.sumOf { it.price }) + CheckoutButton(totalPrice = 100.0) + } + } + ) +} + +@Composable +fun CartItem(product: Product) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 8.dp), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { + Text(text = product.name, fontSize = 20.sp) + Text(text = "$${product.priceUsd}", fontSize = 20.sp) + } +} + +@Composable +fun CheckoutButton(totalPrice: Double) { + Button( + onClick = { /* TODO: Add checkout logic */ }, + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 16.dp) + ) { + Text(text = "Checkout ($${String.format("%.2f", totalPrice)})") + } +} \ No newline at end of file diff --git a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ProductCard.kt b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/products/ProductCard.kt similarity index 90% rename from demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ProductCard.kt rename to demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/products/ProductCard.kt index 10c19ddc7..2645fc8c5 100644 --- a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ProductCard.kt +++ b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/products/ProductCard.kt @@ -1,7 +1,6 @@ -package io.opentelemetry.android.demo.ui.shop +package io.opentelemetry.android.demo.ui.shop.products import android.graphics.Bitmap -import android.util.Log import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -15,7 +14,6 @@ import androidx.compose.material3.CardColors import androidx.compose.material3.CardDefaults import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.asImageBitmap @@ -25,13 +23,12 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.navigation.NavController -import io.opentelemetry.android.demo.TAG import io.opentelemetry.android.demo.clients.ImageLoader import io.opentelemetry.android.demo.gothamFont import io.opentelemetry.android.demo.model.Product @Composable -fun ProductCard(product: Product, navController: NavController) { +fun ProductCard(product: Product) { val imageLoader = ImageLoader(LocalContext.current) val sourceProductImage = imageLoader.load(product.picture) Bitmap.createScaledBitmap(sourceProductImage, 120, 120, false) @@ -48,7 +45,6 @@ fun ProductCard(product: Product, navController: NavController) { .wrapContentHeight() .padding(20.dp), onClick = { - navController.navigate("prod-details/${product.id}") // Log.d(TAG, "TODO: Implement me!") } ) { diff --git a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ProductDetails.kt b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/products/ProductDetails.kt similarity index 90% rename from demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ProductDetails.kt rename to demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/products/ProductDetails.kt index 3ddbcefb5..5b0a30e20 100644 --- a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ProductDetails.kt +++ b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/products/ProductDetails.kt @@ -1,4 +1,4 @@ -package io.opentelemetry.android.demo.ui.shop +package io.opentelemetry.android.demo.ui.shop.products import androidx.compose.foundation.Image import androidx.compose.foundation.layout.* @@ -6,20 +6,16 @@ import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material3.* import androidx.compose.runtime.* -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import io.opentelemetry.android.demo.clients.ImageLoader import io.opentelemetry.android.demo.gothamFont -import io.opentelemetry.android.demo.model.PriceUsd import io.opentelemetry.android.demo.model.Product -import io.opentelemetry.android.demo.theme.DemoAppTheme @Composable fun ProductDetails(product:Product){ diff --git a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ProductList.kt b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/products/ProductList.kt similarity index 69% rename from demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ProductList.kt rename to demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/products/ProductList.kt index 48b2c77b6..44d8907ad 100644 --- a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ProductList.kt +++ b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/products/ProductList.kt @@ -1,4 +1,4 @@ -package io.opentelemetry.android.demo.ui.shop +package io.opentelemetry.android.demo.ui.shop.products import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row @@ -6,18 +6,17 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.runtime.Composable -import androidx.compose.runtime.State import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.navigation.NavController import io.opentelemetry.android.demo.model.Product @Composable -fun ProductList(products: State>, navController: NavController) { +fun ProductList(products: List) { LazyColumn(modifier = Modifier.fillMaxSize()) { - items(products.value.size) { index -> + items(products.size) { index -> Row() { - ProductCard(products.value[index], navController = navController) + ProductCard(products[index]) } } item { From 43f48030df5c94c2e156aa28bcf6da15783e2358 Mon Sep 17 00:00:00 2001 From: Magda Wojtowicz Date: Tue, 30 Jul 2024 21:07:42 +0200 Subject: [PATCH 05/11] exit to main activity added --- .../demo/ui/shop/AstronomyShopActivity.kt | 38 +++++----- .../android/demo/ui/shop/Navigation.kt | 74 +++++++------------ 2 files changed, 45 insertions(+), 67 deletions(-) diff --git a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/AstronomyShopActivity.kt b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/AstronomyShopActivity.kt index 42ecd39dd..2fd5df5f2 100644 --- a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/AstronomyShopActivity.kt +++ b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/AstronomyShopActivity.kt @@ -16,6 +16,7 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.Surface import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -32,7 +33,6 @@ import io.opentelemetry.android.demo.ui.shop.products.ProductList class AstronomyShopActivity : AppCompatActivity() { - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { @@ -42,40 +42,43 @@ class AstronomyShopActivity : AppCompatActivity() { } @Composable -fun AstronomyShopScreen(){ +fun AstronomyShopScreen() { val productsClient = ProductCatalogClient(LocalContext.current) val products by remember { mutableStateOf(productsClient.get()) } + val context = LocalContext.current + val astronomyShopNavController = rememberAstronomyShopNavController() DemoAppTheme { Surface( modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background ) { - val astronomyShopNavController = rememberAstronomyShopNavController() Scaffold( bottomBar = { - BottomNavigationBar(navController = astronomyShopNavController.navController, + BottomNavigationBar( + items = listOf(BottomNavItem.Exit, BottomNavItem.List, BottomNavItem.Cart), + currentRoute = astronomyShopNavController.currentRoute, + onItemClicked = { route -> + astronomyShopNavController.navController.navigate(route) { + popUpTo(astronomyShopNavController.navController.graph.startDestinationId) + launchSingleTop = true + } + }, onExitClicked = { -// TODO + val intent = Intent(context, MainActivity::class.java) + context.startActivity(intent) + (context as? Activity)?.finish() } ) - } ) { innerPadding -> NavHost( navController = astronomyShopNavController.navController, - startDestination = "prod-list", - Modifier.padding(innerPadding) // Ensure proper padding with Scaffold + startDestination = MainDestinations.HOME_ROUTE, + Modifier.padding(innerPadding) ) { - composable("prod-list") { - ProductList( - products = products - ) - } composable(BottomNavItem.List.route) { - ProductList( - products = products - ) + ProductList(products = products) } composable(BottomNavItem.Cart.route) { CartScreen() @@ -85,6 +88,3 @@ fun AstronomyShopScreen(){ } } } - - - diff --git a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/Navigation.kt b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/Navigation.kt index cd40dc501..3d37e3ada 100644 --- a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/Navigation.kt +++ b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/Navigation.kt @@ -28,38 +28,6 @@ sealed class BottomNavItem(val route: String, val icon: ImageVector, val label: object Cart : BottomNavItem("cart", Icons.Filled.ShoppingCart, "Cart") } -@Composable -fun BottomNavigationBar(navController: NavController, onExitClicked: () -> Unit) { - NavigationBar { - val navBackStackEntry by navController.currentBackStackEntryAsState() - val currentRoute = navBackStackEntry?.destination?.route - - - val items = listOf( - BottomNavItem.Exit, - BottomNavItem.List, - BottomNavItem.Cart - ) - - items.forEach { item -> - NavigationBarItem( - selected = currentRoute == item.route, - onClick = { - if (item.route == BottomNavItem.Exit.route) { - onExitClicked() - } else { - navController.navigate(item.route) { - popUpTo(navController.graph.startDestinationId) - launchSingleTop = true - } - } - }, - icon = { Icon(item.icon, contentDescription = item.label) }, - label = { Text(item.label) } - ) - } - } -} object MainDestinations { const val HOME_ROUTE = "prod-list" @@ -74,9 +42,7 @@ fun rememberAstronomyShopNavController(navController: NavHostController = rememb AstronomyShopNavController(navController) } -/** - * Responsible for holding UI Navigation logic. - */ + @Stable class AstronomyShopNavController( val navController: NavHostController, @@ -88,19 +54,6 @@ class AstronomyShopNavController( navController.navigateUp() } - fun navigateToBottomBarRoute(route: String) { - if (route != currentRoute) { - navController.navigate(route) { - launchSingleTop = true - restoreState = true - // Pop up backstack to the first destination and save state. This makes going back - // to the start destination when pressing back in any other bottom tab. - popUpTo(findStartDestination(navController.graph).id) { - saveState = true - } - } - } - } fun navigateToProductDetail(productId: String, from: NavBackStackEntry) { // In order to discard duplicated navigation events, we check the Lifecycle if (from.lifecycleIsResumed()) { @@ -130,3 +83,28 @@ private tailrec fun findStartDestination(graph: NavDestination): NavDestination return if (graph is NavGraph) findStartDestination(graph.startDestination!!) else graph } +@Composable +fun BottomNavigationBar( + items: List, + currentRoute: String?, + onItemClicked: (String) -> Unit, + onExitClicked: () -> Unit +) { + NavigationBar { + items.forEach { item -> + NavigationBarItem( + selected = currentRoute == item.route, + onClick = { + if (item.route == BottomNavItem.Exit.route) { + onExitClicked() + } else { + onItemClicked(item.route) + } + }, + icon = { Icon(item.icon, contentDescription = item.label) }, + label = { Text(item.label) } + ) + } + } +} + From 80407c9f8652c8ca33a832fafb8e2e96ed4c2c05 Mon Sep 17 00:00:00 2001 From: Magda Wojtowicz Date: Tue, 30 Jul 2024 21:07:48 +0200 Subject: [PATCH 06/11] navigation to product details added to refactored navigation --- .../demo/ui/dashboard/DashboardFragment.kt | 52 ------------- .../demo/ui/dashboard/DashboardViewModel.kt | 18 ----- .../demo/ui/shop/AstronomyShopActivity.kt | 11 ++- .../android/demo/ui/shop/Navigation.kt | 57 +++++++------- .../android/demo/ui/shop/ShopFragment.kt | 77 ------------------- .../demo/ui/shop/products/ProductCard.kt | 34 ++++---- .../demo/ui/shop/products/ProductList.kt | 8 +- .../res/layout/activity_astronomy_shop.xml | 28 +------ .../main/res/layout/fragment_dashboard.xml | 22 ------ .../src/main/res/layout/fragment_home.xml | 22 ------ .../main/res/navigation/mobile_navigation.xml | 25 ------ 11 files changed, 62 insertions(+), 292 deletions(-) delete mode 100644 demo-app/src/main/java/io/opentelemetry/android/demo/ui/dashboard/DashboardFragment.kt delete mode 100644 demo-app/src/main/java/io/opentelemetry/android/demo/ui/dashboard/DashboardViewModel.kt delete mode 100644 demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ShopFragment.kt delete mode 100644 demo-app/src/main/res/layout/fragment_dashboard.xml delete mode 100644 demo-app/src/main/res/layout/fragment_home.xml delete mode 100644 demo-app/src/main/res/navigation/mobile_navigation.xml diff --git a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/dashboard/DashboardFragment.kt b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/dashboard/DashboardFragment.kt deleted file mode 100644 index 9a4481934..000000000 --- a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/dashboard/DashboardFragment.kt +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.android.demo.ui.dashboard - -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.TextView -import androidx.fragment.app.Fragment -import androidx.lifecycle.ViewModelProvider -import io.opentelemetry.android.demo.databinding.FragmentDashboardBinding - -class DashboardFragment : Fragment() { - // Renamed from _binding (default) due to ktlint problem below - private var binding: FragmentDashboardBinding? = null - - // This property is only valid between onCreateView and onDestroyView. - // Currently failing ktlint due to - // https://github.com/pinterest/ktlint/issues/2448 - // which hasn't hit the aging gradle spotless plugin yet -// private val binding get() = _binding!! - fun getBinding(): FragmentDashboardBinding { - return binding!! - } - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle?, - ): View { - val dashboardViewModel = - ViewModelProvider(this).get(DashboardViewModel::class.java) - - binding = FragmentDashboardBinding.inflate(inflater, container, false) - val root: View = getBinding().root - - val textView: TextView = getBinding().textDashboard - dashboardViewModel.text.observe(viewLifecycleOwner) { - textView.text = it - } - return root - } - - override fun onDestroyView() { - super.onDestroyView() - binding = null - } -} diff --git a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/dashboard/DashboardViewModel.kt b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/dashboard/DashboardViewModel.kt deleted file mode 100644 index af4464db2..000000000 --- a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/dashboard/DashboardViewModel.kt +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.android.demo.ui.dashboard - -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.ViewModel - -class DashboardViewModel : ViewModel() { - private val _text = - MutableLiveData().apply { - value = "This is dashboard Fragment" - } - val text: LiveData = _text -} diff --git a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/AstronomyShopActivity.kt b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/AstronomyShopActivity.kt index 2fd5df5f2..feb6edee1 100644 --- a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/AstronomyShopActivity.kt +++ b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/AstronomyShopActivity.kt @@ -16,7 +16,6 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.material3.Surface import androidx.compose.runtime.Composable -import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -31,7 +30,6 @@ import io.opentelemetry.android.demo.ui.shop.cart.CartScreen import io.opentelemetry.android.demo.ui.shop.products.ProductDetails import io.opentelemetry.android.demo.ui.shop.products.ProductList - class AstronomyShopActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -78,11 +76,18 @@ fun AstronomyShopScreen() { Modifier.padding(innerPadding) ) { composable(BottomNavItem.List.route) { - ProductList(products = products) + ProductList(products = products) { productId -> + astronomyShopNavController.navigateToProductDetail(productId) + } } composable(BottomNavItem.Cart.route) { CartScreen() } + composable("${MainDestinations.PRODUCT_DETAIL_ROUTE}/{${MainDestinations.PRODUCT_ID_KEY}}") { backStackEntry -> + val productId = backStackEntry.arguments?.getString(MainDestinations.PRODUCT_ID_KEY) + val product = products.find { it.id == productId } + product?.let { ProductDetails(product = it) } + } } } } diff --git a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/Navigation.kt b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/Navigation.kt index 3d37e3ada..ca59ea93e 100644 --- a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/Navigation.kt +++ b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/Navigation.kt @@ -28,7 +28,6 @@ sealed class BottomNavItem(val route: String, val icon: ImageVector, val label: object Cart : BottomNavItem("cart", Icons.Filled.ShoppingCart, "Cart") } - object MainDestinations { const val HOME_ROUTE = "prod-list" const val PRODUCT_DETAIL_ROUTE = "product" @@ -42,7 +41,6 @@ fun rememberAstronomyShopNavController(navController: NavHostController = rememb AstronomyShopNavController(navController) } - @Stable class AstronomyShopNavController( val navController: NavHostController, @@ -54,35 +52,40 @@ class AstronomyShopNavController( navController.navigateUp() } - fun navigateToProductDetail(productId: String, from: NavBackStackEntry) { - // In order to discard duplicated navigation events, we check the Lifecycle - if (from.lifecycleIsResumed()) { - navController.navigate("${MainDestinations.PRODUCT_DETAIL_ROUTE}/$productId") - } + fun navigateToProductDetail(productId: String) { + navController.navigate("${MainDestinations.PRODUCT_DETAIL_ROUTE}/$productId") } -} - -/** - * If the lifecycle is not resumed it means this NavBackStackEntry already processed a nav event. - * - * This is used to de-duplicate navigation events. - */ -private fun NavBackStackEntry.lifecycleIsResumed() = - this.lifecycle.currentState == Lifecycle.State.RESUMED - -private val NavGraph.startDestination: NavDestination? - get() = findNode(startDestinationId) - -/** - * Copied from similar function in NavigationUI.kt - * - * https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:navigation/navigation-ui/src/main/java/androidx/navigation/ui/NavigationUI.kt - */ -private tailrec fun findStartDestination(graph: NavDestination): NavDestination { - return if (graph is NavGraph) findStartDestination(graph.startDestination!!) else graph +// fun navigateToProductDetail(productId: String, from: NavBackStackEntry) { +// // In order to discard duplicated navigation events, we check the Lifecycle +// if (from.lifecycleIsResumed()) { +// navController.navigate("${MainDestinations.PRODUCT_DETAIL_ROUTE}/$productId") +// } +// } } +//some stuff copied from android samples +// +///** +// * If the lifecycle is not resumed it means this NavBackStackEntry already processed a nav event. +// * +// * This is used to de-duplicate navigation events. +// */ +//private fun NavBackStackEntry.lifecycleIsResumed() = +// this.lifecycle.currentState == Lifecycle.State.RESUMED +// +//private val NavGraph.startDestination: NavDestination? +// get() = findNode(startDestinationId) +// +///** +// * Copied from similar function in NavigationUI.kt +// * +// * https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:navigation/navigation-ui/src/main/java/androidx/navigation/ui/NavigationUI.kt +// */ +//private tailrec fun findStartDestination(graph: NavDestination): NavDestination { +// return if (graph is NavGraph) findStartDestination(graph.startDestination!!) else graph +//} + @Composable fun BottomNavigationBar( items: List, diff --git a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ShopFragment.kt b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ShopFragment.kt deleted file mode 100644 index d99883ab6..000000000 --- a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/ShopFragment.kt +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.android.demo.ui.shop - -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -import androidx.compose.runtime.mutableStateOf -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.ComposeView -import androidx.fragment.app.Fragment -import androidx.navigation.NavType -import androidx.navigation.compose.NavHost -import androidx.navigation.compose.composable -import androidx.navigation.compose.rememberNavController -import androidx.navigation.navArgument -import io.opentelemetry.android.demo.clients.ProductCatalogClient -import io.opentelemetry.android.demo.theme.DemoAppTheme -import io.opentelemetry.android.demo.ui.shop.products.ProductDetails -import io.opentelemetry.android.demo.ui.shop.products.ProductList - -class ShopFragment : Fragment() { -// -// override fun onCreateView( -// inflater: LayoutInflater, -// container: ViewGroup?, -// savedInstanceState: Bundle?, -// ): View { -// -// val productsClient = ProductCatalogClient(requireContext()) -// val products = productsClient.get() -// val productState = mutableStateOf(products) -// -// return ComposeView(requireContext()).apply { -// setContent { -// -// val navController = rememberNavController() -// -// DemoAppTheme { -// // A surface container using the 'background' color from the theme -// Surface( -// modifier = Modifier.fillMaxSize(), -// color = MaterialTheme.colorScheme.background, -// ) { -// NavHost(navController = navController, startDestination = "prod-list") { -// composable("prod-list") { -// ProductList( -// products = productState, -// navController = navController -// ) -// } -// composable( -// "prod-details/{productId}", -// arguments = listOf(navArgument("productId") { -// type = NavType.StringType -// }) -// ) { backStackEntry -> -// val productId = backStackEntry.arguments?.getString("productId") -// val product = products.find { it.id == productId } -// product?.let { -// ProductDetails(product = it) -// } -// } -// } -// } -// } -// } -// } -// } -} diff --git a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/products/ProductCard.kt b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/products/ProductCard.kt index 2645fc8c5..9362d5738 100644 --- a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/products/ProductCard.kt +++ b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/products/ProductCard.kt @@ -28,27 +28,28 @@ import io.opentelemetry.android.demo.gothamFont import io.opentelemetry.android.demo.model.Product @Composable -fun ProductCard(product: Product) { +fun ProductCard(product: Product, onClick: (String) -> Unit) { val imageLoader = ImageLoader(LocalContext.current) val sourceProductImage = imageLoader.load(product.picture) Bitmap.createScaledBitmap(sourceProductImage, 120, 120, false) -// Bitmap.createBitmap() val cardColors = CardColors( containerColor = Color.White, contentColor = Color.Black, disabledContentColor = Color.Black, disabledContainerColor = Color.Black ) - Card(elevation = CardDefaults.cardElevation(defaultElevation = 10.dp), + Card( + elevation = CardDefaults.cardElevation(defaultElevation = 10.dp), colors = cardColors, - modifier = Modifier.fillMaxSize() - .height(200.dp) - .wrapContentHeight() - .padding(20.dp), - onClick = { -// Log.d(TAG, "TODO: Implement me!") - } + modifier = Modifier + .fillMaxSize() + .height(200.dp) + .wrapContentHeight() + .padding(20.dp), + onClick = { onClick(product.id) } ) { - Row(modifier = Modifier.fillMaxSize().padding(20.dp)) { + Row(modifier = Modifier + .fillMaxSize() + .padding(20.dp)) { Row(modifier = Modifier.fillMaxWidth()) { Column { Image( @@ -57,14 +58,17 @@ fun ProductCard(product: Product) { ) } Column(modifier = Modifier.fillMaxWidth()) { - Text(product.name + "\n\n$" + product.priceValue(), fontFamily = gothamFont, + Text( + product.name + "\n\n$" + product.priceValue(), + fontFamily = gothamFont, style = TextStyle.Default.copy(textAlign = TextAlign.Right), fontSize = 18.sp, - modifier = Modifier.padding(start = 15.dp, top = 25.dp).fillMaxWidth() + modifier = Modifier + .padding(start = 15.dp, top = 25.dp) + .fillMaxWidth() ) - } } } } -} \ No newline at end of file +} diff --git a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/products/ProductList.kt b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/products/ProductList.kt index 44d8907ad..34ed11d7d 100644 --- a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/products/ProductList.kt +++ b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/products/ProductList.kt @@ -12,11 +12,11 @@ import androidx.navigation.NavController import io.opentelemetry.android.demo.model.Product @Composable -fun ProductList(products: List) { +fun ProductList(products: List, onProductClick: (String) -> Unit) { LazyColumn(modifier = Modifier.fillMaxSize()) { items(products.size) { index -> - Row() { - ProductCard(products[index]) + Row { + ProductCard(products[index], onClick = onProductClick) } } item { @@ -25,4 +25,4 @@ fun ProductList(products: List) { ) } } -} \ No newline at end of file +} diff --git a/demo-app/src/main/res/layout/activity_astronomy_shop.xml b/demo-app/src/main/res/layout/activity_astronomy_shop.xml index 87f9dba2c..cd1f2df91 100644 --- a/demo-app/src/main/res/layout/activity_astronomy_shop.xml +++ b/demo-app/src/main/res/layout/activity_astronomy_shop.xml @@ -4,30 +4,4 @@ android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" - android:paddingTop="?attr/actionBarSize"> - - - - - - \ No newline at end of file + android:paddingTop="?attr/actionBarSize"/> \ No newline at end of file diff --git a/demo-app/src/main/res/layout/fragment_dashboard.xml b/demo-app/src/main/res/layout/fragment_dashboard.xml deleted file mode 100644 index 166ab0e9e..000000000 --- a/demo-app/src/main/res/layout/fragment_dashboard.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - \ No newline at end of file diff --git a/demo-app/src/main/res/layout/fragment_home.xml b/demo-app/src/main/res/layout/fragment_home.xml deleted file mode 100644 index 5778483d8..000000000 --- a/demo-app/src/main/res/layout/fragment_home.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - \ No newline at end of file diff --git a/demo-app/src/main/res/navigation/mobile_navigation.xml b/demo-app/src/main/res/navigation/mobile_navigation.xml deleted file mode 100644 index da4972c97..000000000 --- a/demo-app/src/main/res/navigation/mobile_navigation.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - \ No newline at end of file From 3391caaa439ba5cefabeb2d7644b74857e61f32b Mon Sep 17 00:00:00 2001 From: Magda Wojtowicz Date: Tue, 30 Jul 2024 21:08:04 +0200 Subject: [PATCH 07/11] navigation to product details added to refactored navigation --- .../android/demo/ui/shop/Navigation.kt | 14 +++++--------- .../android/demo/ui/shop/products/ProductCard.kt | 1 - .../android/demo/ui/shop/products/ProductList.kt | 1 - 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/Navigation.kt b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/Navigation.kt index ca59ea93e..411cd793b 100644 --- a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/Navigation.kt +++ b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/Navigation.kt @@ -3,8 +3,6 @@ package io.opentelemetry.android.demo.ui.shop import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.filled.ExitToApp import androidx.compose.material.icons.automirrored.filled.List -import androidx.compose.material.icons.filled.ExitToApp -import androidx.compose.material.icons.filled.List import androidx.compose.material.icons.filled.ShoppingCart import androidx.compose.material3.Icon import androidx.compose.runtime.Composable @@ -13,19 +11,17 @@ import androidx.compose.runtime.remember import androidx.compose.ui.graphics.vector.ImageVector import androidx.lifecycle.Lifecycle import androidx.navigation.NavBackStackEntry -import androidx.navigation.NavController import androidx.navigation.NavDestination import androidx.navigation.NavGraph import androidx.navigation.NavHostController import androidx.navigation.compose.rememberNavController import androidx.compose.material3.* -import androidx.compose.runtime.getValue -import androidx.navigation.compose.currentBackStackEntryAsState + sealed class BottomNavItem(val route: String, val icon: ImageVector, val label: String) { - object Exit : BottomNavItem("home", Icons.AutoMirrored.Filled.ExitToApp, "Exit") - object List : BottomNavItem("prod-list", Icons.AutoMirrored.Filled.List, "List") - object Cart : BottomNavItem("cart", Icons.Filled.ShoppingCart, "Cart") + data object Exit : BottomNavItem("home", Icons.AutoMirrored.Filled.ExitToApp, "Exit") + data object List : BottomNavItem("prod-list", Icons.AutoMirrored.Filled.List, "List") + data object Cart : BottomNavItem("cart", Icons.Filled.ShoppingCart, "Cart") } object MainDestinations { @@ -64,7 +60,7 @@ class AstronomyShopNavController( // } } -//some stuff copied from android samples +//some stuff copied from android samples commented for now // ///** // * If the lifecycle is not resumed it means this NavBackStackEntry already processed a nav event. diff --git a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/products/ProductCard.kt b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/products/ProductCard.kt index 9362d5738..e5100efa9 100644 --- a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/products/ProductCard.kt +++ b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/products/ProductCard.kt @@ -22,7 +22,6 @@ import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import androidx.navigation.NavController import io.opentelemetry.android.demo.clients.ImageLoader import io.opentelemetry.android.demo.gothamFont import io.opentelemetry.android.demo.model.Product diff --git a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/products/ProductList.kt b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/products/ProductList.kt index 34ed11d7d..8c26bd1f9 100644 --- a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/products/ProductList.kt +++ b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/products/ProductList.kt @@ -8,7 +8,6 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import androidx.navigation.NavController import io.opentelemetry.android.demo.model.Product @Composable From 7b8224aac4243088a9890854870bea54121ad8c2 Mon Sep 17 00:00:00 2001 From: Magda Wojtowicz Date: Tue, 30 Jul 2024 21:09:40 +0200 Subject: [PATCH 08/11] removed anused folders --- .../android/demo/ui/cart/CartFragment.kt | 52 ------------------- .../android/demo/ui/cart/CartViewModel.kt | 18 ------- 2 files changed, 70 deletions(-) delete mode 100644 demo-app/src/main/java/io/opentelemetry/android/demo/ui/cart/CartFragment.kt delete mode 100644 demo-app/src/main/java/io/opentelemetry/android/demo/ui/cart/CartViewModel.kt diff --git a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/cart/CartFragment.kt b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/cart/CartFragment.kt deleted file mode 100644 index 2e039c40c..000000000 --- a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/cart/CartFragment.kt +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.android.demo.ui.cart - -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.TextView -import androidx.fragment.app.Fragment -import androidx.lifecycle.ViewModelProvider -import io.opentelemetry.android.demo.databinding.FragmentNotificationsBinding - -class CartFragment : Fragment() { - // Renamed from _binding (default) due to ktlint problem below - private var binding: FragmentNotificationsBinding? = null - - // This property is only valid between onCreateView and onDestroyView. - // Currently failing ktlint due to - // https://github.com/pinterest/ktlint/issues/2448 - // which hasn't hit the aging gradle spotless plugin yet -// private val binding get() = _binding!! - private fun getBinding(): FragmentNotificationsBinding { - return binding!! - } - - override fun onCreateView( - inflater: LayoutInflater, - container: ViewGroup?, - savedInstanceState: Bundle?, - ): View { - val cartViewModel = - ViewModelProvider(this).get(CartViewModel::class.java) - - binding = FragmentNotificationsBinding.inflate(inflater, container, false) - val root: View = getBinding().root - - val textView: TextView = getBinding().textNotifications - cartViewModel.text.observe(viewLifecycleOwner) { - textView.text = it - } - return root - } - - override fun onDestroyView() { - super.onDestroyView() - binding = null - } -} diff --git a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/cart/CartViewModel.kt b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/cart/CartViewModel.kt deleted file mode 100644 index b2c5a207b..000000000 --- a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/cart/CartViewModel.kt +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.android.demo.ui.cart - -import androidx.lifecycle.LiveData -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.ViewModel - -class CartViewModel : ViewModel() { - private val _text = - MutableLiveData().apply { - value = "This is cart Fragment" - } - val text: LiveData = _text -} From f3fe52bbec046a7c4663ff190b7723b56fd2ad87 Mon Sep 17 00:00:00 2001 From: Magda Wojtowicz Date: Tue, 30 Jul 2024 21:09:48 +0200 Subject: [PATCH 09/11] removed accidental comflict resolution duplicates --- demo-app/gradle/libs.versions.toml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/demo-app/gradle/libs.versions.toml b/demo-app/gradle/libs.versions.toml index ab03437cf..8786f1288 100644 --- a/demo-app/gradle/libs.versions.toml +++ b/demo-app/gradle/libs.versions.toml @@ -36,10 +36,6 @@ androidx-constraintlayout = { group = "androidx.constraintlayout", name = "const material = { group = "com.google.android.material", name = "material", version = "1.12.0" } androidx-lifecycle-livedata-ktx = { group = "androidx.lifecycle", name = "lifecycle-livedata-ktx", version = "2.8.4" } androidx-lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version = "2.8.4" } -androidx-navigation-fragment-ktx = { group = "androidx.navigation", name = "navigation-fragment-ktx", version = "2.7.7" } -androidx-navigation-ui-ktx = { group = "androidx.navigation", name = "navigation-ui-ktx", version = "2.7.7" } -androidx-lifecycle-livedata-ktx = { group = "androidx.lifecycle", name = "lifecycle-livedata-ktx", version = "2.8.3" } -androidx-lifecycle-viewmodel-ktx = { group = "androidx.lifecycle", name = "lifecycle-viewmodel-ktx", version = "2.8.3" } androidx-navigation-fragment-ktx = { group = "androidx.navigation", name = "navigation-fragment-ktx", version.ref = "navigation-compose" } androidx-navigation-ui-ktx = { group = "androidx.navigation", name = "navigation-ui-ktx", version.ref = "navigation-compose" } androidx-navigation-compose = {group = "androidx.navigation", name = "navigation-compose", version.ref = "navigation-compose"} From c873bd96dbb80851567706be704a0161db69fe46 Mon Sep 17 00:00:00 2001 From: Magda Wojtowicz Date: Wed, 31 Jul 2024 12:34:26 +0200 Subject: [PATCH 10/11] removed dead code --- .../android/demo/ui/shop/Navigation.kt | 30 ------------------- 1 file changed, 30 deletions(-) diff --git a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/Navigation.kt b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/Navigation.kt index 411cd793b..77cbff18c 100644 --- a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/Navigation.kt +++ b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/Navigation.kt @@ -52,36 +52,6 @@ class AstronomyShopNavController( navController.navigate("${MainDestinations.PRODUCT_DETAIL_ROUTE}/$productId") } -// fun navigateToProductDetail(productId: String, from: NavBackStackEntry) { -// // In order to discard duplicated navigation events, we check the Lifecycle -// if (from.lifecycleIsResumed()) { -// navController.navigate("${MainDestinations.PRODUCT_DETAIL_ROUTE}/$productId") -// } -// } -} - -//some stuff copied from android samples commented for now -// -///** -// * If the lifecycle is not resumed it means this NavBackStackEntry already processed a nav event. -// * -// * This is used to de-duplicate navigation events. -// */ -//private fun NavBackStackEntry.lifecycleIsResumed() = -// this.lifecycle.currentState == Lifecycle.State.RESUMED -// -//private val NavGraph.startDestination: NavDestination? -// get() = findNode(startDestinationId) -// -///** -// * Copied from similar function in NavigationUI.kt -// * -// * https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:navigation/navigation-ui/src/main/java/androidx/navigation/ui/NavigationUI.kt -// */ -//private tailrec fun findStartDestination(graph: NavDestination): NavDestination { -// return if (graph is NavGraph) findStartDestination(graph.startDestination!!) else graph -//} - @Composable fun BottomNavigationBar( items: List, From cdf64fb3be7f10b91cfddd3309d24656d81e4fb5 Mon Sep 17 00:00:00 2001 From: Magda Wojtowicz Date: Wed, 31 Jul 2024 16:36:06 +0200 Subject: [PATCH 11/11] sight changes in cart screen placeholder --- .../io/opentelemetry/android/demo/ui/shop/Navigation.kt | 5 +++-- .../io/opentelemetry/android/demo/ui/shop/cart/Cart.kt | 7 +++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/Navigation.kt b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/Navigation.kt index 77cbff18c..76942e2e8 100644 --- a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/Navigation.kt +++ b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/Navigation.kt @@ -52,6 +52,8 @@ class AstronomyShopNavController( navController.navigate("${MainDestinations.PRODUCT_DETAIL_ROUTE}/$productId") } +} + @Composable fun BottomNavigationBar( items: List, @@ -75,5 +77,4 @@ fun BottomNavigationBar( ) } } -} - +} \ No newline at end of file diff --git a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/cart/Cart.kt b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/cart/Cart.kt index 4015577ba..a0781e841 100644 --- a/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/cart/Cart.kt +++ b/demo-app/src/main/java/io/opentelemetry/android/demo/ui/shop/cart/Cart.kt @@ -15,7 +15,7 @@ import io.opentelemetry.android.demo.model.Product @Composable fun CartScreen() { -// val products + val products : List = listOf() Scaffold( content = { innerPadding -> Column( @@ -27,10 +27,9 @@ fun CartScreen() { LazyColumn( modifier = Modifier.weight(1f) ) { -// this.items(products) { product -> CartItem(product) } + items(products.size) { index -> CartItem(products[index]) } } -// CheckoutButton(totalPrice = products.sumOf { it.price }) - CheckoutButton(totalPrice = 100.0) + CheckoutButton(totalPrice = products.sumOf { it.priceValue() }) } } )