This commit is contained in:
Dimitris
2026-03-15 17:18:02 +01:00
parent 619ceb9f83
commit 5198725879
46 changed files with 840 additions and 1326 deletions

View File

@@ -13,8 +13,8 @@ android {
applicationId = "com.kouros.navigation"
minSdk = 33
targetSdk = 36
versionCode = 66
versionName = "0.2.0.66"
versionCode = 68
versionName = "0.2.0.68"
base.archivesName = "navi-$versionName"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}

View File

@@ -10,6 +10,7 @@ import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.annotation.RequiresPermission
import androidx.appcompat.app.AppCompatDelegate
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
@@ -172,11 +173,13 @@ class MainActivity : ComponentActivity() {
}
enableEdgeToEdge()
setContent {
CheckPermissionScreen(app = {
AppNavGraph(
mainActivity = this
)
})
NavigationTheme {
CheckPermissionScreen(app = {
AppNavGraph(
mainActivity = this
)
})
}
}
}
@@ -185,9 +188,14 @@ class MainActivity : ComponentActivity() {
fun StartScreen(
navController: NavHostController
) {
val appViewModel: AppViewModel = appViewModel()
val darkMode by appViewModel.darkMode.collectAsState()
if (darkMode == 1) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
} else {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
}
val baseStyle = BaseStyleModel().readStyle(applicationContext, darkMode, darkMode == 1)
val locationProvider = rememberDefaultLocationProvider(
updateInterval = 0.5.seconds, desiredAccuracy = DesiredAccuracy.Highest

View File

@@ -16,10 +16,37 @@ fun AppNavGraph(mainActivity: MainActivity) {
val navController = rememberNavController()
NavHost(navController = navController, startDestination = "startScreen") {
composable("startScreen") { mainActivity.StartScreen(navController) }
composable("display_settings") { SettingsRoute("display_settings", navController) { navController.popBackStack() } }
composable("nav_settings") { SettingsRoute("nav_settings", navController) { navController.popBackStack() } }
composable("settings") { SettingsRoute("settings", navController) { navController.popBackStack() } }
composable("search") { SearchScreen(navController, navController.context, navigationViewModel, mainActivity.lastLocation) { navController.popBackStack() }
composable("display_settings") {
SettingsRoute(
"display_settings",
navController
) { navController.popBackStack() }
}
composable("nav_settings") {
SettingsRoute(
"nav_settings",
navController
) { navController.popBackStack() }
}
composable("settings") {
SettingsRoute(
"settings",
navController
) { navController.popBackStack() }
}
composable("search") {
SearchScreen(
navController,
navController.context,
navigationViewModel,
mainActivity.lastLocation
) { navController.popBackStack() }
}
composable("settings_screen") {
SettingsRoute(
"settings_screen",
navController
) { navController.popBackStack() }
}
}
}

View File

@@ -3,8 +3,10 @@ package com.kouros.navigation.ui.search
import android.annotation.SuppressLint
import android.content.Context
import android.location.Location
import androidx.appcompat.app.AppCompatDelegate
import androidx.compose.foundation.clickable
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
@@ -28,14 +30,17 @@ import androidx.compose.material3.Scaffold
import androidx.compose.material3.SearchBar
import androidx.compose.material3.SearchBarDefaults
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
@@ -49,8 +54,11 @@ import com.kouros.navigation.data.Place
import com.kouros.navigation.data.PlaceColor
import com.kouros.navigation.data.nominatim.SearchResult
import com.kouros.navigation.model.NavigationViewModel
import com.kouros.navigation.ui.app.AppViewModel
import com.kouros.navigation.ui.app.appViewModel
import com.kouros.navigation.ui.theme.NavigationTheme
import com.kouros.navigation.utils.location
import kotlin.math.roundToInt
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
@@ -64,10 +72,18 @@ fun SearchScreen(
function: () -> Unit
) {
NavigationTheme(true) {
val appViewModel: AppViewModel = appViewModel()
val darkMode by appViewModel.darkMode.collectAsState()
if (darkMode == 1 || darkMode == 2 && isSystemInDarkTheme()) {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
} else {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
}
//NavigationTheme(darkMode == 1 || darkMode == 2 && isSystemInDarkTheme()) {
Scaffold(
topBar = {
CenterAlignedTopAppBar(
TopAppBar(
title = {
Text(
stringResource(id = R.string.search_action_title),
@@ -92,7 +108,7 @@ fun SearchScreen(
Categories(context, navigationViewModel, location, closeSheet = { })
}
}
}
// }
}
@OptIn(ExperimentalMaterial3Api::class)
@@ -118,9 +134,6 @@ fun SearchBar(
}
SearchBar(
colors = SearchBarDefaults.colors(
containerColor = MaterialTheme.colorScheme.secondaryContainer
),
inputField = {
SearchBarDefaults.InputField(
modifier = Modifier.focusRequester(focusRequester),
@@ -206,11 +219,11 @@ private fun SearchPlaces(
) {
val color = remember { PlaceColor }
LazyColumn(
contentPadding = PaddingValues(horizontal = 16.dp, vertical = 10.dp),
contentPadding = PaddingValues(horizontal = 6.dp, vertical = 10.dp),
verticalArrangement = Arrangement.spacedBy(4.dp),
) {
items(searchResults, key = { it.placeId }) { place ->
Row {
Row(verticalAlignment = Alignment.CenterVertically) {
Icon(
painter = painterResource(id = R.drawable.ic_place_white_24dp),
"Navigation",
@@ -218,8 +231,11 @@ private fun SearchPlaces(
modifier = Modifier.size(24.dp, 24.dp),
)
ListItem(
headlineContent = { Text(place.displayName) },
headlineContent = {Text(place.address.road)},
leadingContent = {Text(place.name)},
trailingContent = { Text("${(place.distance/1000).roundToInt()} km") },
modifier = Modifier
.animateItem()
.clickable {
val pl = Place(
name = place.name,

View File

@@ -160,7 +160,7 @@ private fun RecentPlaces(
Icon(
painter = painterResource(id = R.drawable.ic_place_white_24dp),
"Navigation",
tint = color.copy(alpha = 1f),
//tint = color.copy(alpha = 1f),
modifier = Modifier.size(24.dp, 24.dp),
)
ListItem(

View File

@@ -1,35 +1,41 @@
package com.kouros.navigation.ui.settings
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.CenterAlignedTopAppBar
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedCard
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SegmentedButtonDefaults.Icon
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
import com.kouros.data.R
import com.kouros.navigation.model.SettingsViewModel
import com.kouros.navigation.ui.components.RadioButtonSingleSelection
import com.kouros.navigation.ui.components.SectionTitle
import com.kouros.navigation.ui.components.SettingSwitch
import com.kouros.navigation.ui.theme.NavigationTheme
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -37,80 +43,100 @@ fun DisplayScreen(viewModel: SettingsViewModel, navigateBack: () -> Unit) {
val darkMode by viewModel.darkMode.collectAsState()
val show3D by viewModel.show3D.collectAsState()
NavigationTheme(useDarkTheme = viewModel.darkMode.collectAsState().value == 1) {
Scaffold(
topBar = {
CenterAlignedTopAppBar(
title = {
Text(
stringResource(id = R.string.display_settings),
val showTraffic by viewModel.traffic.collectAsState()
val distanceMode by viewModel.distanceMode.collectAsState()
Scaffold(
topBar = {
TopAppBar(
title = {
Text(
stringResource(id = R.string.display_settings),
)
},
navigationIcon = {
IconButton(onClick = navigateBack) {
Icon(
painter = painterResource(R.drawable.arrow_back_24px),
contentDescription = stringResource(id = R.string.accept_action_title),
modifier = Modifier.size(48.dp, 48.dp),
)
},
navigationIcon = {
IconButton(onClick = navigateBack) {
Icon(
painter = painterResource(R.drawable.arrow_back_24px),
contentDescription = stringResource(id = R.string.accept_action_title),
modifier = Modifier.size(48.dp, 48.dp),
)
}
},
)
},
)
{ padding ->
val scrollState = rememberScrollState()
Column(
modifier = Modifier
.fillMaxSize()
.padding(top = 20.dp)
.verticalScroll(scrollState)
) {
}
},
)
},
)
{ paddingValues ->
val scrollState = rememberScrollState()
Column(
modifier = Modifier
.padding(paddingValues)
.fillMaxSize()
.padding(top = 10.dp)
.verticalScroll(scrollState)
) {
OutlinedCard(modifier = Modifier.fillMaxWidth()) {
Column(
modifier = Modifier.padding(10.dp),
) {
SettingSwitch(
title = stringResource(R.string.threed_building),
checked = show3D,
onCheckedChange = viewModel::onShow3DChanged
)
Text(
text = stringResource(R.string.settings_action_title),
style = MaterialTheme.typography.headlineMedium
)
SettingSwitch(
title = stringResource(R.string.traffic),
checked = showTraffic,
onCheckedChange = viewModel::onTraffic
)
}
}
Spacer(modifier = Modifier.height(24.dp))
Spacer(modifier = Modifier.height(20.dp))
// Appearance
SectionTitle(stringResource(R.string.threed_building))
OutlinedCard(modifier = Modifier.fillMaxWidth()) {
Column(
modifier = Modifier.padding(10.dp),
) {
SectionTitle(stringResource(R.string.dark_mode))
SettingSwitch(
title = stringResource(R.string.threed_building),
checked = show3D,
onCheckedChange = viewModel::onShow3DChanged
)
val radioOptions = listOf(
stringResource(R.string.off_action_title),
stringResource(R.string.on_action_title),
stringResource(R.string.use_telephon_settings)
)
RadioButtonSingleSelection(
modifier = Modifier.padding(),
selectedOption = darkMode,
radioOptions = radioOptions,
onClick = viewModel::onDarkModeChanged
)
}
}
SectionTitle(stringResource(R.string.dark_mode))
Spacer(modifier = Modifier.height(20.dp))
val radioOptions = listOf(
stringResource(R.string.off_action_title),
stringResource(R.string.on_action_title),
stringResource(R.string.use_telephon_settings)
)
RadioButtonSingleSelection(
modifier = Modifier.padding(),
selectedOption = darkMode,
radioOptions = radioOptions,
onClick = viewModel::onDarkModeChanged
)
OutlinedCard(modifier = Modifier.fillMaxWidth()) {
Column(
modifier = Modifier.padding(10.dp),
) {
SectionTitle(stringResource(R.string.distance_units))
val radioOptions = listOf(
stringResource(R.string.automatically),
stringResource(R.string.kilometer),
stringResource(R.string.miles)
)
RadioButtonSingleSelection(
modifier = Modifier.padding(),
selectedOption = distanceMode,
radioOptions = radioOptions,
onClick = viewModel::onDistanceModeChanged
)
}
}
}
}
}

View File

@@ -1,7 +1,10 @@
package com.kouros.navigation.ui.settings
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
@@ -10,9 +13,11 @@ import androidx.compose.material3.CenterAlignedTopAppBar
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.OutlinedCard
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
@@ -38,16 +43,14 @@ import com.kouros.navigation.ui.theme.NavigationTheme
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun NavigationScreen(viewModel: SettingsViewModel, navigateBack: () -> Unit) {
NavigationTheme(useDarkTheme = viewModel.darkMode.collectAsState().value == 1) {
Scaffold(
topBar = {
CenterAlignedTopAppBar(
title = {
Text(
stringResource(id = R.string.navigation_settings),
)
},
Scaffold(
topBar = {
TopAppBar(
title = {
Text(
stringResource(id = R.string.navigation_settings),
)
},
navigationIcon = {
IconButton(onClick = navigateBack) {
Icon(
@@ -57,19 +60,17 @@ fun NavigationScreen(viewModel: SettingsViewModel, navigateBack: () -> Unit) {
)
}
},
)
},
) { padding ->
val scrollState = rememberScrollState()
Column(
modifier =
Modifier
.consumeWindowInsets(padding)
.verticalScroll(scrollState)
.padding(top = padding.calculateTopPadding()),
) {
NavigationSettings(viewModel)
}
)
},
) { padding ->
val scrollState = rememberScrollState()
Column(
modifier =
Modifier
.padding(padding)
.verticalScroll(scrollState)
) {
NavigationSettings(viewModel)
}
}
}
@@ -82,49 +83,63 @@ fun NavigationSettings(viewModel: SettingsViewModel) {
val routingEngine by viewModel.routingEngine.collectAsState()
val tomTomApiKey by viewModel.tomTomApiKey.collectAsState()
SettingSwitch(
title = stringResource(R.string.avoid_highways_row_title),
checked = avoidMotorway,
onCheckedChange = viewModel::onAvoidMotorway
)
OutlinedCard(modifier = Modifier.fillMaxWidth()) {
Column(
modifier = Modifier.padding(10.dp),
) {
SettingSwitch(
title = stringResource(R.string.avoid_highways_row_title),
checked = avoidMotorway,
onCheckedChange = viewModel::onAvoidMotorway
)
SettingSwitch(
title = stringResource(R.string.avoid_tolls_row_title),
checked = avoidTollway,
onCheckedChange = viewModel::onAvoidTollway
)
SettingSwitch(
title = stringResource(R.string.avoid_tolls_row_title),
checked = avoidTollway,
onCheckedChange = viewModel::onAvoidTollway
)
SettingSwitch(
title = stringResource(R.string.use_car_location),
checked = carLocation,
onCheckedChange = viewModel::onCarLocation
)
SettingSwitch(
title = stringResource(R.string.use_car_location),
checked = carLocation,
onCheckedChange = viewModel::onCarLocation
)
}
}
SectionTitle(stringResource(R.string.routing_engine))
Spacer(modifier = Modifier.height(20.dp))
val routingEngineOptions = listOf(
stringResource(R.string.valhalla),
stringResource(R.string.osrm),
stringResource(R.string.tomtom)
)
RadioButtonSingleSelection(
modifier = Modifier.padding(),
selectedOption = routingEngine,
radioOptions = routingEngineOptions,
onClick = viewModel::onRoutingEngineChanged
)
OutlinedCard(modifier = Modifier.fillMaxWidth()) {
Column(
modifier = Modifier.padding(10.dp),
) {
SectionTitle(stringResource(R.string.routing_engine))
if (routingEngine == RouteEngine.TOMTOM.ordinal) {
var key by remember { mutableStateOf(tomTomApiKey) }
TextField(
value = key,
onValueChange = {
viewModel.onTomTomApiKeyChanged(it)
key = it
},
label = { Text(stringResource(R.string.tomtom_api_key)) },
textStyle = TextStyle(color = Color.Green, fontWeight = FontWeight.Bold),
modifier = Modifier.padding(20.dp)
)
val routingEngineOptions = listOf(
stringResource(R.string.valhalla),
stringResource(R.string.osrm),
stringResource(R.string.tomtom)
)
RadioButtonSingleSelection(
modifier = Modifier.padding(),
selectedOption = routingEngine,
radioOptions = routingEngineOptions,
onClick = viewModel::onRoutingEngineChanged
)
if (routingEngine == RouteEngine.TOMTOM.ordinal) {
var key by remember { mutableStateOf(tomTomApiKey) }
TextField(
value = key,
onValueChange = {
viewModel.onTomTomApiKeyChanged(it)
key = it
},
label = { Text(stringResource(R.string.tomtom_api_key)) },
textStyle = TextStyle(color = Color.Green, fontWeight = FontWeight.Bold),
modifier = Modifier.padding(20.dp)
)
}
}
}
}

View File

@@ -0,0 +1,120 @@
package com.kouros.navigation.ui.settings
import androidx.appcompat.app.AppCompatDelegate
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedCard
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
import com.kouros.data.R
import com.kouros.navigation.model.SettingsViewModel
import com.kouros.navigation.ui.theme.NavigationTheme
data class Settings(val id: String, val name: String, val icon: Int)
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun Settings(
viewModel: SettingsViewModel,
navController: NavHostController,
navigateBack: () -> Unit
) {
val items = listOf(
Settings(
id = "favorites_screen",
name = "Favoriten",
icon = R.drawable.ic_favorite_white_24dp
),
Settings(
id = "settings_screen",
name = "Einstellungen",
icon = R.drawable.speed_camera_24px
),
Settings(id = "info_screen", name = "Info", icon = R.drawable.ic_place_white_24dp),
)
Scaffold(
topBar = {
TopAppBar(
title = { Text(stringResource(id = R.string.settings_action_title)) },
)
},
) { paddingValues ->
LazyColumn(
modifier = Modifier
.padding(paddingValues)
.padding(8.dp),
) {
item {
Spacer(modifier = Modifier.height(10.dp))
}
items(items) { subItem ->
ScreenItem(item = subItem, onClick = { navController.navigate(subItem.id) })
Spacer(modifier = Modifier.height(10.dp))
}
}
}
}
@Composable
fun ScreenItem(
item: Settings,
onClick: (Settings) -> Unit,
) {
OutlinedCard(onClick = { onClick(item) }, modifier = Modifier.fillMaxWidth()) {
Row(
modifier = Modifier.padding(10.dp),
horizontalArrangement = Arrangement.spacedBy(10.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Icon(
painter = painterResource(item.icon),
contentDescription = stringResource(id = R.string.accept_action_title),
modifier = Modifier.align(Alignment.CenterVertically),
)
Column(
modifier = Modifier.weight(1f),
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
Text(text = item.name, style = MaterialTheme.typography.titleMedium)
}
IconForward()
}
}
}
@Composable
fun RowScope.IconForward() {
Icon(
painter = painterResource(R.drawable.arrow_back_24px),
contentDescription = stringResource(id = R.string.on_action_title),
modifier = Modifier.align(Alignment.CenterVertically),
)
}

View File

@@ -34,6 +34,9 @@ fun SettingsRoute(route: String, navController: NavHostController, function: ()
NavigationScreen (viewModel = viewModel, function)
}
if (route == "settings") {
Settings(viewModel, navController, function)
}
if (route == "settings_screen") {
SettingsScreen(viewModel, navController, function)
}
}

View File

@@ -1,20 +1,24 @@
package com.kouros.navigation.ui.settings
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.consumeWindowInsets
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Button
import androidx.compose.material3.CenterAlignedTopAppBar
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedCard
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
@@ -24,49 +28,79 @@ import com.kouros.data.R
import com.kouros.navigation.model.SettingsViewModel
import com.kouros.navigation.ui.theme.NavigationTheme
data class Item(val id: String, val name: String, val description: String, val icon: Int)
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SettingsScreen(viewModel: SettingsViewModel, navController: NavHostController, navigateBack: () -> Unit) {
NavigationTheme(useDarkTheme = viewModel.darkMode.collectAsState().value == 1) {
Scaffold(
topBar = {
CenterAlignedTopAppBar(
title = {
Text(
stringResource(id = R.string.settings_action_title),
)
},
navigationIcon = {
IconButton(onClick = navigateBack) {
Icon(
painter = painterResource(R.drawable.arrow_back_24px),
contentDescription = stringResource(id = R.string.accept_action_title),
modifier = Modifier.size(48.dp, 48.dp),
)
}
},
)
},
) { padding ->
val scrollState = rememberScrollState()
Column(
modifier =
Modifier
.consumeWindowInsets(padding)
.verticalScroll(scrollState)
.padding(top = padding.calculateTopPadding()),
) {
Column(modifier = Modifier.padding(16.dp)) {
fun SettingsScreen(
viewModel: SettingsViewModel,
navController: NavHostController,
navigateBack: () -> Unit
) {
Button(onClick = { navController.navigate("display_settings") }) {
Text(stringResource(R.string.display_settings))
}
Button(onClick = { navController.navigate("nav_settings") }) {
Text(stringResource(R.string.navigation_settings))
}
}
val items = listOf(
Item(
id = "display_settings",
name = "Display Settings",
description = "",
icon = R.drawable.dark_mode_24px
),
Item(
id = "nav_settings",
name = "Navigation Settings",
description = "",
icon = R.drawable.navigation_24px
)
)
Scaffold(
topBar = {
TopAppBar(
title = { Text("Settings") },
)
},
) { paddingValues ->
LazyColumn(
modifier = Modifier
.padding(paddingValues)
.padding(8.dp),
) {
item {
Spacer(modifier = Modifier.height(10.dp))
}
items(items) { subItem ->
ScreenItem(item = subItem, onClick = { navController.navigate(subItem.id) })
Spacer(modifier = Modifier.height(10.dp))
}
}
}
}
@Composable
fun ScreenItem(
item: Item,
onClick: (Item) -> Unit,
) {
OutlinedCard(onClick = { onClick(item) }, modifier = Modifier.fillMaxWidth()) {
Row(
modifier = Modifier.padding(10.dp),
horizontalArrangement = Arrangement.spacedBy(10.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Icon(
painter = painterResource(item.icon),
contentDescription = stringResource(id = R.string.accept_action_title),
modifier = Modifier.align(Alignment.CenterVertically),
)
Column(
modifier = Modifier.weight(1f),
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
Text(text = item.name, style = MaterialTheme.typography.titleMedium)
}
IconForward()
}
}
}

View File

@@ -84,28 +84,24 @@ private val DarkColors = darkColorScheme(
@Composable
fun NavigationTheme(
useDarkTheme: Boolean = isSystemInDarkTheme(),
dynamicColor: Boolean = true,
content: @Composable () -> Unit
) {
val context = LocalContext.current
val colors = run {
if (useDarkTheme) dynamicDarkColorScheme(context)
else dynamicLightColorScheme(context)
}
val view = LocalView.current
if (!view.isInEditMode) {
SideEffect {
val window = (view.context as Activity).window
window.statusBarColor = colors.primary.toArgb()
WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars =
useDarkTheme
val colorScheme = when {
dynamicColor -> {
val context = LocalContext.current
if (useDarkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
}
MaterialTheme(
colorScheme = if (useDarkTheme) DarkColors else colorScheme,
typography = typography,
content = content,
shapes = shapes,
)
useDarkTheme -> DarkColors
else -> LightColors
}
MaterialTheme(
colorScheme = colorScheme,
typography = typography,
content = content,
shapes = shapes,
)
}