Skip to content

Commit

Permalink
Demo app: activity with fragments (#570)
Browse files Browse the repository at this point in the history
* refactored packages to make more sense with the fragment activity

* added new activity "AboutActicity" which purpose is to display fragment lifecycle instrumentation and 2 fragments within it. Creted buttom nav menu to navigate between these fragments and to return to main activity. Added a "Learn more" button to main activity that launches the About Activity.

* added some content to the AppFeaturesFragment

* set contentDescription for an image to avoid warnings

* added some content for the AboutOpenTelemetryFragment, for now hard written into the layout file.

* made unnecessarily global vars local

* changed activities' labels

* changed button name from OpentStore to Launcher
  • Loading branch information
magda-woj authored Sep 4, 2024
1 parent 5a230fc commit eefc4ac
Show file tree
Hide file tree
Showing 31 changed files with 383 additions and 70 deletions.
9 changes: 7 additions & 2 deletions demo-app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,14 @@
android:usesCleartextTraffic="true"
tools:targetApi="31">
<activity
android:name=".ui.shop.AstronomyShopActivity"
android:name=".shop.ui.AstronomyShopActivity"
android:exported="true"
android:label="@string/title_activity_astronomy_shop"
android:label="Astronomy Shop"
/>
<activity
android:name=".about.AboutActivity"
android:exported="true"
android:label="About OpenTelemetry Android"
/>
<activity
android:name=".MainActivity"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp

@Composable
fun OpenStoreButton(
fun LauncherButton(
text: String,
onClick: () -> Unit,
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import io.opentelemetry.android.demo.about.AboutActivity
import io.opentelemetry.android.demo.theme.DemoAppTheme
import io.opentelemetry.android.demo.ui.shop.AstronomyShopActivity
import io.opentelemetry.android.demo.shop.ui.AstronomyShopActivity

class MainActivity : ComponentActivity() {
private val viewModel by viewModels<DemoViewModel>()
Expand Down Expand Up @@ -73,9 +74,13 @@ class MainActivity : ComponentActivity() {
painterResource(id = R.drawable.otel_icon),
)
val context = LocalContext.current
OpenStoreButton(text = "Click to begin", onClick = {
LauncherButton(text = "Go shopping", onClick = {
context.startActivity(Intent(this@MainActivity, AstronomyShopActivity::class.java))
})
LauncherButton(text = "Learn more", onClick = {
context.startActivity(Intent(this@MainActivity, AboutActivity::class.java))
})

}
}
Log.d(TAG, "Main Activity started ")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package io.opentelemetry.android.demo.about

import android.content.Intent
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.google.android.material.bottomnavigation.BottomNavigationView
import io.opentelemetry.android.demo.MainActivity
import io.opentelemetry.android.demo.R

class AboutActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_about)

val bottomNavigationView: BottomNavigationView = findViewById(R.id.bottom_navigation)

if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container, AppFeaturesFragment())
.commit()
bottomNavigationView.selectedItemId = R.id.navigation_app_features
}

bottomNavigationView.setOnItemSelectedListener { item ->
when (item.itemId) {
R.id.navigation_exit -> {
val intent = Intent(this, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
startActivity(intent)
finish()
true
}
R.id.navigation_app_features -> {
supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container, AppFeaturesFragment())
.commit()
true
}
R.id.navigation_about_opentelemetry -> {
supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container, AboutOpenTelemetryFragment())
.commit()
true
}
else -> false
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package io.opentelemetry.android.demo.about

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import io.opentelemetry.android.demo.R

class AboutOpenTelemetryFragment : Fragment() {

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_about_opentelemetry, container, false)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package io.opentelemetry.android.demo.about

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import io.opentelemetry.android.demo.R

class AppFeaturesFragment : Fragment() {

override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_app_features, container, false)
lateinit var featureAdapter: FeatureAdapter
val features = getFeatureList()
val recyclerView: RecyclerView = view.findViewById(R.id.recyclerView)

featureAdapter = FeatureAdapter(features)
recyclerView.adapter = featureAdapter
recyclerView.layoutManager = LinearLayoutManager(requireContext())

return view
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package io.opentelemetry.android.demo.about

data class Feature(
val title: String,
val description: String,
var isExpanded: Boolean = false
)

fun getFeatureList(): List<Feature> {
return listOf(
Feature(
"Android Activity Lifecycle Monitoring",
"""
- Automatically captures spans for key lifecycle events:
- Created: Includes `onCreate`, `onStart`, `onResume`,
- Paused: Includes `onPause`,
- Stopped: Includes `onStop`,
- Destroyed: Includes `onDestroy`.
- This covers the entire Activity lifecycle, providing detailed insights into each phase.
""".trimIndent()
),
Feature(
"ANR Detection",
"""
- Automatically detects and reports ANRs in the app.
- ANR events are captured as spans with detailed stack traces, providing insights into the exact operations that caused the ANR.
- The span includes key attributes such as `screen.name`, `session.id`, and network information to assist in diagnosing the issue.
""".trimIndent()
),
Feature(
"Slow Render Detection",
"""
- Automatically detects instances of slow rendering within the app.
- Slow render events are captured as spans, providing information on when and where rendering delays occurred.
- The span includes attributes such as `activity.name`, `screen.name`, `count`, and network details to help diagnose performance issues.
""".trimIndent()
),
Feature(
"Manual Instrumentation",
"""
- Provides access to the OpenTelemetry APIs for manual instrumentation, allowing developers to create custom spans and events as needed.
""".trimIndent()
)
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package io.opentelemetry.android.demo.about

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import io.opentelemetry.android.demo.R

class FeatureAdapter(private val features: List<Feature>) : RecyclerView.Adapter<FeatureAdapter.FeatureViewHolder>() {

inner class FeatureViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val titleTextView: TextView = itemView.findViewById(R.id.titleTextView)
private val descriptionTextView: TextView = itemView.findViewById(R.id.descriptionTextView)
private val arrowImageView: ImageView = itemView.findViewById(R.id.arrowImageView)

fun bind(feature: Feature) {
titleTextView.text = feature.title
descriptionTextView.text = feature.description
descriptionTextView.visibility = if (feature.isExpanded) View.VISIBLE else View.GONE
arrowImageView.rotation = if (feature.isExpanded) 180f else 0f

itemView.setOnClickListener {
feature.isExpanded = !feature.isExpanded
notifyItemChanged(adapterPosition)
}
}
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FeatureViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_feature, parent, false)
return FeatureViewHolder(view)
}

override fun onBindViewHolder(holder: FeatureViewHolder, position: Int) {
holder.bind(features[position])
}

override fun getItemCount(): Int = features.size

}

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.opentelemetry.android.demo.clients
package io.opentelemetry.android.demo.shop.clients

import android.content.Context
import android.graphics.Bitmap
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package io.opentelemetry.android.demo.clients
package io.opentelemetry.android.demo.shop.clients

import android.content.Context
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import io.opentelemetry.android.demo.model.Product
import io.opentelemetry.android.demo.model.ProductDeserializationWrapper
import io.opentelemetry.android.demo.shop.model.Product
import io.opentelemetry.android.demo.shop.model.ProductDeserializationWrapper

const val PRODUCTS_FILE = "products.json"

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.opentelemetry.android.demo.clients
package io.opentelemetry.android.demo.shop.clients

import io.opentelemetry.android.demo.model.Product
import io.opentelemetry.android.demo.ui.shop.cart.CartViewModel
import io.opentelemetry.android.demo.shop.model.Product
import io.opentelemetry.android.demo.shop.ui.cart.CartViewModel

class RecommendationService(
private val productCatalogClient: ProductCatalogClient,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.opentelemetry.android.demo.model
package io.opentelemetry.android.demo.shop.model

data class Product(
val id: String,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.android.demo.ui.shop
package io.opentelemetry.android.demo.shop.ui

import android.app.Activity
import android.content.Intent
Expand All @@ -24,19 +24,18 @@ 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.shop.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
import io.opentelemetry.android.demo.ui.shop.cart.CartViewModel
import io.opentelemetry.android.demo.shop.ui.cart.CartScreen
import io.opentelemetry.android.demo.shop.ui.products.ProductDetails
import io.opentelemetry.android.demo.shop.ui.products.ProductList
import io.opentelemetry.android.demo.shop.ui.cart.CartViewModel
import androidx.lifecycle.viewmodel.compose.viewModel
import io.opentelemetry.android.demo.ui.shop.cart.InfoScreen
import io.opentelemetry.android.demo.shop.ui.cart.InfoScreen

class AstronomyShopActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
title = "Astronomy Shop"
setContent {
AstronomyShopScreen()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.opentelemetry.android.demo.ui.shop
package io.opentelemetry.android.demo.shop.ui

import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ExitToApp
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.opentelemetry.android.demo.ui.shop.cart
package io.opentelemetry.android.demo.shop.ui.cart

import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
Expand All @@ -8,13 +8,13 @@ import androidx.compose.ui.Modifier
import java.util.Locale
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import io.opentelemetry.android.demo.ui.shop.products.ProductCard
import io.opentelemetry.android.demo.shop.ui.products.ProductCard
import androidx.compose.ui.Alignment
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import io.opentelemetry.android.demo.clients.ProductCatalogClient
import io.opentelemetry.android.demo.clients.RecommendationService
import io.opentelemetry.android.demo.ui.shop.products.RecommendedSection
import io.opentelemetry.android.demo.shop.clients.ProductCatalogClient
import io.opentelemetry.android.demo.shop.clients.RecommendationService
import io.opentelemetry.android.demo.shop.ui.products.RecommendedSection

@Composable
fun CartScreen(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.opentelemetry.android.demo.ui.shop.cart
package io.opentelemetry.android.demo.shop.ui.cart

import androidx.lifecycle.ViewModel
import io.opentelemetry.android.demo.model.Product
import io.opentelemetry.android.demo.shop.model.Product
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.opentelemetry.android.demo.ui.shop.cart
package io.opentelemetry.android.demo.shop.ui.cart

import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
Expand All @@ -15,7 +15,7 @@ import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.unit.dp
import io.opentelemetry.android.demo.ui.shop.components.UpPressButton
import io.opentelemetry.android.demo.shop.ui.components.UpPressButton
import androidx.compose.ui.Alignment
import androidx.compose.ui.text.style.TextAlign

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.opentelemetry.android.demo.ui.shop.components
package io.opentelemetry.android.demo.shop.ui.components

import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.opentelemetry.android.demo.ui.shop.components
package io.opentelemetry.android.demo.shop.ui.components

import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
Expand Down
Loading

0 comments on commit eefc4ac

Please sign in to comment.