From 8b175937f4c8c49f5a0e17281bc9b914f29a2bb6 Mon Sep 17 00:00:00 2001 From: Maximilian Goldschmidt Date: Mon, 27 May 2024 19:06:14 +0200 Subject: [PATCH] Added compose activity for testing --- automotive/build.gradle | 16 ++- automotive/src/carapp/AndroidManifest.xml | 1 + .../carApp/CarStatsViewerScreen.kt | 2 +- .../ixam97/carStatsViewer/carApp/MenuTab.kt | 15 ++- .../carStatsViewer/compose/ComposeActivity.kt | 108 ++++++++++++++++++ .../compose/ComposeViewModel.kt | 28 +++++ .../compose/components/CarIconButton.kt | 29 +++++ .../compose/components/CarSwitchRow.kt | 40 +++++++ .../carStatsViewer/compose/theme/Color.kt | 13 +++ .../carStatsViewer/compose/theme/Shape.kt | 11 ++ .../carStatsViewer/compose/theme/Theme.kt | 34 ++++++ .../carStatsViewer/compose/theme/Type.kt | 30 +++++ 12 files changed, 322 insertions(+), 5 deletions(-) create mode 100644 automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/ComposeActivity.kt create mode 100644 automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/ComposeViewModel.kt create mode 100644 automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/components/CarIconButton.kt create mode 100644 automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/components/CarSwitchRow.kt create mode 100644 automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/theme/Color.kt create mode 100644 automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/theme/Shape.kt create mode 100644 automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/theme/Theme.kt create mode 100644 automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/theme/Type.kt diff --git a/automotive/build.gradle b/automotive/build.gradle index a92a554d..78b2bcc7 100644 --- a/automotive/build.gradle +++ b/automotive/build.gradle @@ -10,8 +10,8 @@ android { defaultConfig { minSdkVersion 29 targetSdkVersion 33 - versionCode 236 - versionName "0.27.0.0030" + versionCode 238 + versionName "0.27.0.0031" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } @@ -30,7 +30,7 @@ android { carapp { dimension "aaos" - applicationId "de.ixam97.carStatsViewer.play" + applicationId "de.ixam97.carStatsViewer.carApp" } dev { @@ -73,6 +73,11 @@ android { // android.car exists since Android 10 (API level 29) Revision 5. useLibrary 'android.car' namespace 'com.ixam97.carStatsViewer' + + + buildFeatures { + compose true + } } aboutLibraries { @@ -101,6 +106,11 @@ dependencies { implementation "androidx.car.app:app:1.7.0-alpha02" implementation "androidx.car.app:app-automotive:1.7.0-alpha02" + implementation 'androidx.activity:activity-compose:1.7.2' + implementation 'androidx.compose.ui:ui:1.6.7' + implementation 'androidx.compose.material:material:1.6.7' + implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.8.0' + implementation("androidx.room:room-ktx:2.5.0") kapt("androidx.room:room-compiler:2.5.0") diff --git a/automotive/src/carapp/AndroidManifest.xml b/automotive/src/carapp/AndroidManifest.xml index 2e18df21..c93bc622 100644 --- a/automotive/src/carapp/AndroidManifest.xml +++ b/automotive/src/carapp/AndroidManifest.xml @@ -74,6 +74,7 @@ + diff --git a/automotive/src/carapp/java/com/ixam97/carStatsViewer/carApp/CarStatsViewerScreen.kt b/automotive/src/carapp/java/com/ixam97/carStatsViewer/carApp/CarStatsViewerScreen.kt index 10e7de3c..724cdf6b 100644 --- a/automotive/src/carapp/java/com/ixam97/carStatsViewer/carApp/CarStatsViewerScreen.kt +++ b/automotive/src/carapp/java/com/ixam97/carStatsViewer/carApp/CarStatsViewerScreen.kt @@ -87,7 +87,7 @@ class CarStatsViewerScreen( } - private var lifecycle = getLifecycle() + // private var lifecycle = getLifecycle() init { diff --git a/automotive/src/carapp/java/com/ixam97/carStatsViewer/carApp/MenuTab.kt b/automotive/src/carapp/java/com/ixam97/carStatsViewer/carApp/MenuTab.kt index 3b55ca96..b0bb399d 100644 --- a/automotive/src/carapp/java/com/ixam97/carStatsViewer/carApp/MenuTab.kt +++ b/automotive/src/carapp/java/com/ixam97/carStatsViewer/carApp/MenuTab.kt @@ -1,17 +1,20 @@ package com.ixam97.carStatsViewer.carApp +import android.car.Car import android.content.Intent import androidx.annotation.OptIn import androidx.car.app.annotations.ExperimentalCarApi import androidx.car.app.model.CarIcon import androidx.car.app.model.ItemList import androidx.car.app.model.ListTemplate +import androidx.car.app.model.ParkedOnlyOnClickListener import androidx.car.app.model.Row import androidx.car.app.model.Toggle import androidx.core.graphics.drawable.IconCompat import com.ixam97.carStatsViewer.BuildConfig import com.ixam97.carStatsViewer.CarStatsViewer import com.ixam97.carStatsViewer.R +import com.ixam97.carStatsViewer.compose.ComposeActivity import com.ixam97.carStatsViewer.ui.activities.DebugActivity import com.ixam97.carStatsViewer.ui.activities.HistoryActivity import com.ixam97.carStatsViewer.ui.activities.MainActivity @@ -29,10 +32,12 @@ internal fun CarStatsViewerScreen.MenuList() = ListTemplate.Builder().apply { val historyActivityIntent = Intent(carContext, HistoryActivity::class.java).apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK } - val debugActivityIntent = Intent(carContext, DebugActivity::class.java).apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK } + val composeActivityIntent = Intent(carContext, ComposeActivity::class.java).apply { + flags = Intent.FLAG_ACTIVITY_NEW_TASK + } setSingleList(ItemList.Builder().apply { addItem(Row.Builder().apply{ @@ -68,6 +73,14 @@ internal fun CarStatsViewerScreen.MenuList() = ListTemplate.Builder().apply { }.setChecked(appPreferences.carAppRealTimeData).build()) }.build()) if (BuildConfig.FLAVOR_version == "dev") { + addItem(Row.Builder().apply { + setTitle("Compose Test UI") + setImage(CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.ic_car_app_debug)).build()) + setBrowsable(true) + setOnClickListener(ParkedOnlyOnClickListener.create { + carContext.startActivity(composeActivityIntent) + }) + }.build()) addItem(Row.Builder().apply{ setTitle("Debug") setImage(CarIcon.Builder(IconCompat.createWithResource(carContext, R.drawable.ic_car_app_debug)).build()) diff --git a/automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/ComposeActivity.kt b/automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/ComposeActivity.kt new file mode 100644 index 00000000..1aeab709 --- /dev/null +++ b/automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/ComposeActivity.kt @@ -0,0 +1,108 @@ +package com.ixam97.carStatsViewer.compose + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.Divider +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.unit.dp +import androidx.lifecycle.viewmodel.compose.viewModel +import com.ixam97.carStatsViewer.CarStatsViewer +import com.ixam97.carStatsViewer.R +import com.ixam97.carStatsViewer.compose.components.CarIconButton +import com.ixam97.carStatsViewer.compose.components.CarSwitchRow +import com.ixam97.carStatsViewer.compose.theme.ComposeTestTheme +import com.ixam97.carStatsViewer.compose.theme.Typography +import com.ixam97.carStatsViewer.compose.theme.darkBackground +import com.ixam97.carStatsViewer.compose.theme.headerBackground +import com.ixam97.carStatsViewer.utils.InAppLogger + +class ComposeActivity: ComponentActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setTheme(R.style.AppTheme) + + val brand = CarStatsViewer.dataProcessor.staticVehicleData.vehicleMake + + InAppLogger.d("brand: $brand") + + setContent { + + ComposeTestTheme(brand) { + + val composeViewModel: ComposeViewModel = viewModel() + + val composeActivityState by composeViewModel.composeActivityState.collectAsState() + + Box(modifier = Modifier + .fillMaxSize() + .padding(15.dp) + .clip(RoundedCornerShape(10.dp)) + .background(color = darkBackground) + ) { + Column( + modifier = Modifier + .fillMaxWidth() + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .background(color = headerBackground), + verticalAlignment = Alignment.CenterVertically + ) { + CarIconButton(onCLick = { finish() }, iconResId = R.drawable.ic_arrow_back) + Spacer(modifier = Modifier.width(10.dp)) + Text(text = "Hello World!", style = Typography.h1) + } + Divider( + modifier = Modifier.height(3.dp), + color = MaterialTheme.colors.secondary + ) + + Column( + modifier = Modifier + .fillMaxSize() + ) { + CarSwitchRow( + switchState = composeActivityState.switchStates[0], + onClick = { composeViewModel.setSwitch(0, !composeActivityState.switchStates[0]) } + ) { + Text(text = "Row 1") + } + CarSwitchRow( + switchState = composeActivityState.switchStates[1], + onClick = { composeViewModel.setSwitch(1, !composeActivityState.switchStates[1]) } + ) { + Text(text = "Row 2") + } + CarSwitchRow( + switchState = composeActivityState.switchStates[2], + onClick = { composeViewModel.setSwitch(2, !composeActivityState.switchStates[2]) } + ) { + Text(text = "Row 3") + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/ComposeViewModel.kt b/automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/ComposeViewModel.kt new file mode 100644 index 00000000..7f9173cc --- /dev/null +++ b/automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/ComposeViewModel.kt @@ -0,0 +1,28 @@ +package com.ixam97.carStatsViewer.compose + +import androidx.lifecycle.ViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.update + +class ComposeViewModel: ViewModel() { + + data class ComposeActivityState( + val switchStates: List = listOf(false, false, false) + ) + + private val _composeActivityState = MutableStateFlow(ComposeActivityState()) + val composeActivityState = _composeActivityState.asStateFlow() + + fun setSwitch(switchIndex: Int, value: Boolean) { + if (switchIndex >= _composeActivityState.value.switchStates.size || switchIndex < 0) return + + _composeActivityState.update { + val newSwitchStates = it.switchStates.toMutableList() + newSwitchStates[switchIndex] = value + it.copy(switchStates = newSwitchStates) + } + } + +} + diff --git a/automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/components/CarIconButton.kt b/automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/components/CarIconButton.kt new file mode 100644 index 00000000..4548f219 --- /dev/null +++ b/automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/components/CarIconButton.kt @@ -0,0 +1,29 @@ +package com.ixam97.carStatsViewer.compose.components + +import androidx.annotation.DrawableRes +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.material.Icon +import androidx.compose.material.IconButton +import androidx.compose.material.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp + +@Composable +fun CarIconButton(onCLick: () -> Unit, @DrawableRes iconResId: Int) { + IconButton( + modifier = Modifier + .padding(10.dp) + .size(70.dp), + onClick = onCLick + ) { + Icon( + painterResource(id = iconResId), + tint = MaterialTheme.colors.secondary, + contentDescription = null + ) + } +} \ No newline at end of file diff --git a/automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/components/CarSwitchRow.kt b/automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/components/CarSwitchRow.kt new file mode 100644 index 00000000..1c63d5ac --- /dev/null +++ b/automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/components/CarSwitchRow.kt @@ -0,0 +1,40 @@ +package com.ixam97.carStatsViewer.compose.components + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.Switch +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.draw.scale +import androidx.compose.ui.unit.dp + +@Composable +fun CarSwitchRow( + switchState: Boolean, + onClick: () -> Unit, + content: @Composable () -> Unit +) { + Row( + modifier = Modifier + .height(100.dp) + .clickable { onClick() } + .padding(horizontal = 30.dp), + verticalAlignment = Alignment.CenterVertically + ) { + content() + Spacer(modifier = Modifier.weight(1f)) + Switch( + modifier = Modifier + .scale(2f) + .padding(horizontal = 10.dp), + checked = switchState, + onCheckedChange = { onClick() } + ) + } +} \ No newline at end of file diff --git a/automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/theme/Color.kt b/automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/theme/Color.kt new file mode 100644 index 00000000..d83e2dd0 --- /dev/null +++ b/automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/theme/Color.kt @@ -0,0 +1,13 @@ +package com.ixam97.carStatsViewer.compose.theme + +import androidx.compose.ui.graphics.Color + +val polestarOrange = Color(0xFFD96C00) +val volvoBlue = Color(0xFF2F6093) + +val darkBackground = Color(0xFF1B1B1B) +val mainBackground = Color(0xFF1F1F1F) +val headerBackground = Color(0xFF282A2D) +val primaryButtonGray = Color(0xFF3E4146) +val primaryGray = Color(0xFF7B858A) +val secondaryGray = Color(0xFFA3B1B8) \ No newline at end of file diff --git a/automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/theme/Shape.kt b/automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/theme/Shape.kt new file mode 100644 index 00000000..b9e52a3d --- /dev/null +++ b/automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/theme/Shape.kt @@ -0,0 +1,11 @@ +package com.ixam97.carStatsViewer.compose.theme + +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.Shapes +import androidx.compose.ui.unit.dp + +val Shapes = Shapes( + small = RoundedCornerShape(4.dp), + medium = RoundedCornerShape(4.dp), + large = RoundedCornerShape(0.dp) +) \ No newline at end of file diff --git a/automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/theme/Theme.kt b/automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/theme/Theme.kt new file mode 100644 index 00000000..caca0222 --- /dev/null +++ b/automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/theme/Theme.kt @@ -0,0 +1,34 @@ +package com.ixam97.carStatsViewer.compose.theme + +import androidx.compose.material.MaterialTheme +import androidx.compose.material.darkColors +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color + +private fun carAppColorPalate(primaryColor: Color? = null) = darkColors( + primary = primaryColor ?: primaryGray, + secondary = primaryColor ?: secondaryGray, + background = darkBackground, + onBackground = Color.White, + surface = darkBackground, + onSurface = Color.White, + onPrimary = Color.White +) + +@Composable +fun ComposeTestTheme(carMake: String? = null, content: @Composable () -> Unit) { + val colors = carAppColorPalate( + primaryColor = when (carMake) { + "Polestar" -> polestarOrange + "Volvo" -> volvoBlue + else -> null + } + ) + + MaterialTheme( + colors = colors, + typography = Typography, + shapes = Shapes, + content = content + ) +} \ No newline at end of file diff --git a/automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/theme/Type.kt b/automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/theme/Type.kt new file mode 100644 index 00000000..cfbf8929 --- /dev/null +++ b/automotive/src/carapp/java/com/ixam97/carStatsViewer/compose/theme/Type.kt @@ -0,0 +1,30 @@ +package com.ixam97.carStatsViewer.compose.theme + +import androidx.compose.material.Typography +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.sp + +// Set of Material typography styles to start with +val Typography = Typography( + defaultFontFamily = FontFamily.Default, + body1 = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 30.sp, + color = Color.White + ), + button = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.W500, + fontSize = 30.sp + ), + h1 = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 35.sp, + color = Color.White + ) +) \ No newline at end of file