Settings
This commit is contained in:
@@ -14,8 +14,8 @@ android {
|
||||
applicationId = "com.kouros.navigation"
|
||||
minSdk = 33
|
||||
targetSdk = 36
|
||||
versionCode = 42
|
||||
versionName = "0.2.0.42"
|
||||
versionCode = 43
|
||||
versionName = "0.2.0.43"
|
||||
base.archivesName = "navi-$versionName"
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
@@ -97,9 +97,6 @@ dependencies {
|
||||
implementation("com.github.ticofab:android-gpx-parser:2.3.1")
|
||||
implementation(libs.androidx.navigation.compose)
|
||||
implementation(libs.kotlinx.serialization.json)
|
||||
implementation("com.github.alorma.compose-settings:ui-tiles:2.25.0")
|
||||
implementation("com.github.alorma.compose-settings:ui-tiles-extended:2.25.0")
|
||||
implementation("com.github.alorma.compose-settings:ui-tiles-expressive:2.25.0")
|
||||
implementation(libs.androidx.foundation.layout)
|
||||
testImplementation(libs.junit)
|
||||
androidTestImplementation(libs.androidx.junit)
|
||||
|
||||
@@ -22,6 +22,8 @@ import androidx.compose.material3.BottomSheetScaffold
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.FloatingActionButton
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.SheetState
|
||||
import androidx.compose.material3.SheetValue
|
||||
import androidx.compose.material3.SnackbarHost
|
||||
import androidx.compose.material3.SnackbarHostState
|
||||
import androidx.compose.material3.Text
|
||||
@@ -34,6 +36,7 @@ import androidx.compose.runtime.mutableDoubleStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
@@ -91,7 +94,7 @@ class MainActivity : ComponentActivity() {
|
||||
|
||||
val routeModel = RouteModel()
|
||||
var tilt = 50.0
|
||||
val useMock = true
|
||||
val useMock = false
|
||||
val type = 3 // 1 simulate 2 test 3 gpx 4 testSingle
|
||||
|
||||
var currentIndex = 0
|
||||
@@ -198,13 +201,12 @@ class MainActivity : ComponentActivity() {
|
||||
|
||||
val appViewModel: AppViewModel = appViewModel()
|
||||
val darkMode by appViewModel.darkMode.collectAsState()
|
||||
|
||||
val sheetPeekHeight = 250.dp
|
||||
baseStyle = BaseStyleModel().readStyle(applicationContext, darkMode, darkMode == 1)
|
||||
|
||||
val scaffoldState = rememberBottomSheetScaffoldState()
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val scope = rememberCoroutineScope()
|
||||
val sheetPeekHeightState = remember { mutableStateOf(256.dp) }
|
||||
val sheetPeekHeightState = remember { mutableStateOf(sheetPeekHeight) }
|
||||
|
||||
val locationProvider = rememberDefaultLocationProvider(
|
||||
updateInterval = 0.5.seconds, desiredAccuracy = DesiredAccuracy.Highest
|
||||
@@ -221,7 +223,7 @@ class MainActivity : ComponentActivity() {
|
||||
fun closeSheet() {
|
||||
scope.launch {
|
||||
scaffoldState.bottomSheetState.partialExpand()
|
||||
sheetPeekHeightState.value = 128.dp
|
||||
sheetPeekHeightState.value = sheetPeekHeight
|
||||
}
|
||||
}
|
||||
NavigationTheme (useDarkTheme = darkMode == 1) {
|
||||
@@ -261,11 +263,11 @@ class MainActivity : ComponentActivity() {
|
||||
|
||||
@Composable
|
||||
fun App() {
|
||||
//val lastRoute = NavigationUtils.getStringKeyValue(applicationContext, Constants.LAST_ROUTE)
|
||||
//if (lastRoute!!.isNotEmpty()) {
|
||||
// routeModel.startNavigation(lastRoute, applicationContext)
|
||||
// routeData.value = routeModel.curRoute.routeGeoJson
|
||||
//}
|
||||
val appViewModel: AppViewModel = appViewModel()
|
||||
val lastRoute by appViewModel.lastRoute.collectAsState()
|
||||
if (lastRoute.isNotEmpty()) {
|
||||
navigationViewModel.route.value = lastRoute
|
||||
}
|
||||
AppNavGraph(applicationContext = applicationContext, this)
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.kouros.navigation.car.map.rememberBaseStyle
|
||||
import com.kouros.navigation.data.StepData
|
||||
import com.kouros.navigation.ui.app.AppViewModel
|
||||
import com.kouros.navigation.ui.app.appViewModel
|
||||
import com.kouros.navigation.utils.settingsViewModel
|
||||
import org.maplibre.compose.camera.CameraPosition
|
||||
import org.maplibre.compose.camera.rememberCameraState
|
||||
import org.maplibre.compose.location.LocationTrackingEffect
|
||||
@@ -66,7 +67,7 @@ fun MapView(
|
||||
val rememberBaseStyle = rememberBaseStyle(baseStyle)
|
||||
|
||||
val appViewModel: AppViewModel = appViewModel()
|
||||
val showBuildings by appViewModel.threedBuilding.collectAsState()
|
||||
val showBuildings by appViewModel.show3D.collectAsState()
|
||||
|
||||
Column {
|
||||
NavigationInfo(step, nextStep)
|
||||
|
||||
@@ -4,10 +4,13 @@ import android.content.Context
|
||||
import android.location.Location
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.wrapContentHeight
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.text.input.TextFieldState
|
||||
@@ -17,6 +20,7 @@ import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.ListItem
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.SearchBar
|
||||
import androidx.compose.material3.SearchBarDefaults
|
||||
import androidx.compose.material3.Text
|
||||
@@ -51,32 +55,36 @@ fun SearchSheet(
|
||||
if (search.value != null) {
|
||||
searchResults.addAll(search.value!!)
|
||||
}
|
||||
val textFieldState = rememberTextFieldState()
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.wrapContentHeight()
|
||||
) {
|
||||
SearchBar(
|
||||
textFieldState = textFieldState,
|
||||
searchPlaces = emptyList(),
|
||||
searchResults = searchResults,
|
||||
viewModel = viewModel,
|
||||
context = applicationContext,
|
||||
location = location,
|
||||
closeSheet = { closeSheet() }
|
||||
|
||||
Home(applicationContext, viewModel, location, closeSheet = { closeSheet() })
|
||||
if (recentPlaces.value != null) {
|
||||
val items = listOf(recentPlaces)
|
||||
if (items.isNotEmpty()) {
|
||||
RecentPlaces(recentPlaces.value!!, viewModel, applicationContext, location, closeSheet)
|
||||
)
|
||||
//Home(applicationContext, viewModel, location, closeSheet = { closeSheet() })
|
||||
if (recentPlaces.value != null) {
|
||||
val items = listOf(recentPlaces)
|
||||
if (items.isNotEmpty()) {
|
||||
RecentPlaces(
|
||||
recentPlaces.value!!,
|
||||
viewModel,
|
||||
applicationContext,
|
||||
location,
|
||||
closeSheet
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
// if (searchResults.isNotEmpty()) {
|
||||
val textFieldState = rememberTextFieldState()
|
||||
val items = listOf(searchResults)
|
||||
// if (items.isNotEmpty()) {
|
||||
SearchBar(
|
||||
textFieldState = textFieldState,
|
||||
searchPlaces = emptyList<Place>(),
|
||||
searchResults = searchResults,
|
||||
viewModel = viewModel,
|
||||
context = applicationContext,
|
||||
location = location,
|
||||
closeSheet = { closeSheet() }
|
||||
|
||||
)
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Composable
|
||||
@@ -124,40 +132,44 @@ fun SearchBar(
|
||||
location: Location,
|
||||
closeSheet: () -> Unit
|
||||
) {
|
||||
var expanded by rememberSaveable { mutableStateOf(true) }
|
||||
SearchBar(
|
||||
inputField = {
|
||||
SearchBarDefaults.InputField(
|
||||
leadingIcon = {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.search_48px),
|
||||
"Search",
|
||||
modifier = Modifier.size(24.dp, 24.dp),
|
||||
)
|
||||
},
|
||||
query = textFieldState.text.toString(),
|
||||
onQueryChange = { textFieldState.edit { replace(0, length, it) } },
|
||||
onSearch = {
|
||||
searchPlaces(viewModel, location, it)
|
||||
expanded = false
|
||||
},
|
||||
expanded = expanded,
|
||||
onExpandedChange = { expanded = it },
|
||||
placeholder = { Text(context.getString(R.string.search_action_title)) }
|
||||
)
|
||||
},
|
||||
expanded = expanded,
|
||||
onExpandedChange = { expanded = it },
|
||||
) {
|
||||
if (searchPlaces.isNotEmpty()) {
|
||||
Text(context.getString(R.string.recent_destinations))
|
||||
RecentPlaces(searchPlaces, viewModel, context, location, closeSheet)
|
||||
}
|
||||
if (searchResults.isNotEmpty()) {
|
||||
Text("Search places")
|
||||
SearchPlaces(searchResults, viewModel, context, location, closeSheet)
|
||||
}
|
||||
var expanded by rememberSaveable { mutableStateOf(false) }
|
||||
SearchBar(
|
||||
colors = SearchBarDefaults.colors(
|
||||
containerColor = MaterialTheme.colorScheme.secondaryContainer
|
||||
),
|
||||
modifier = modifier,
|
||||
inputField = {
|
||||
SearchBarDefaults.InputField(
|
||||
leadingIcon = {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.search_48px),
|
||||
"Search",
|
||||
modifier = Modifier.size(24.dp, 24.dp),
|
||||
)
|
||||
},
|
||||
query = textFieldState.text.toString(),
|
||||
onQueryChange = { textFieldState.edit { replace(0, length, it) } },
|
||||
onSearch = {
|
||||
searchPlaces(viewModel, location, it)
|
||||
expanded = false
|
||||
},
|
||||
expanded = expanded,
|
||||
onExpandedChange = { expanded = it },
|
||||
placeholder = { Text(context.getString(R.string.search_action_title)) }
|
||||
)
|
||||
},
|
||||
expanded = expanded,
|
||||
onExpandedChange = { expanded = it },
|
||||
) {
|
||||
if (searchPlaces.isNotEmpty()) {
|
||||
Text(context.getString(R.string.recent_destinations))
|
||||
RecentPlaces(searchPlaces, viewModel, context, location, closeSheet)
|
||||
}
|
||||
if (searchResults.isNotEmpty()) {
|
||||
Text("Search places")
|
||||
SearchPlaces(searchResults, viewModel, context, location, closeSheet)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun searchPlaces(viewModel: NavigationViewModel, location: Location, it: String) {
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
package com.kouros.navigation.ui
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.consumeWindowInsets
|
||||
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.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
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
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
|
||||
@Composable
|
||||
fun SettingsScreen(navController: NavHostController, navigateBack: () -> Unit) {
|
||||
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)) {
|
||||
|
||||
Button(onClick = { navController.navigate("display_settings") }) {
|
||||
Text(stringResource(R.string.display_settings))
|
||||
}
|
||||
Button(onClick = { navController.navigate("nav_settings") }) {
|
||||
Text(stringResource(R.string.navigation_settings))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,10 +18,17 @@ class AppViewModel(
|
||||
0
|
||||
)
|
||||
|
||||
val threedBuilding = settingsRepository.threedBuildingFlow
|
||||
val show3D = settingsRepository.show3DFlow
|
||||
.stateIn(
|
||||
viewModelScope,
|
||||
SharingStarted.Eagerly,
|
||||
false
|
||||
)
|
||||
|
||||
val lastRoute = settingsRepository.lastRouteFlow
|
||||
.stateIn(
|
||||
viewModelScope,
|
||||
SharingStarted.Eagerly,
|
||||
""
|
||||
)
|
||||
}
|
||||
@@ -6,9 +6,6 @@ import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import com.kouros.navigation.ui.MainActivity
|
||||
import com.kouros.navigation.ui.settings.NavigationScreenSettings
|
||||
import com.kouros.navigation.ui.SettingsScreen
|
||||
import com.kouros.navigation.ui.settings.DisplaySettings
|
||||
import com.kouros.navigation.ui.settings.SettingsRoute
|
||||
|
||||
|
||||
@@ -18,17 +15,8 @@ fun AppNavGraph(applicationContext: Context, mainActivity: MainActivity) {
|
||||
val navController = rememberNavController()
|
||||
NavHost(navController = navController, startDestination = "startScreen") {
|
||||
composable("startScreen") { mainActivity.StartScreen(navController) }
|
||||
composable("settings") { SettingsScreen(navController) { navController.popBackStack() } }
|
||||
composable("settingsxx") {
|
||||
SettingsRoute("display_settings", navController) { navController.popBackStack() }
|
||||
}
|
||||
// old
|
||||
//composable("display_settings") { DisplaySettings(applicationContext) { navController.popBackStack() } }
|
||||
//composable("nav_settings") { NavigationScreenSettings(applicationContext) { navController.popBackStack() } }
|
||||
|
||||
// new
|
||||
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() } }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
package com.kouros.navigation.ui.settings
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
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.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.Scaffold
|
||||
import androidx.compose.material3.SegmentedButtonDefaults.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
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
|
||||
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),
|
||||
)
|
||||
},
|
||||
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)
|
||||
) {
|
||||
|
||||
Text(
|
||||
text = stringResource(R.string.settings_action_title),
|
||||
style = MaterialTheme.typography.headlineMedium
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
|
||||
// Appearance
|
||||
SectionTitle(stringResource(R.string.threed_building))
|
||||
|
||||
SettingSwitch(
|
||||
title = stringResource(R.string.threed_building),
|
||||
checked = show3D,
|
||||
onCheckedChange = viewModel::onShow3DChanged
|
||||
)
|
||||
|
||||
SectionTitle(stringResource(R.string.dark_mode))
|
||||
|
||||
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
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,155 +0,0 @@
|
||||
package com.kouros.navigation.ui.settings
|
||||
|
||||
import android.content.Context
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ColumnScope
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.consumeWindowInsets
|
||||
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.Card
|
||||
import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.CenterAlignedTopAppBar
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.alorma.compose.settings.ui.SettingsCheckbox
|
||||
import com.alorma.compose.settings.ui.SettingsGroup
|
||||
import com.alorma.compose.settings.ui.SettingsRadioButton
|
||||
import com.alorma.compose.settings.ui.base.internal.LocalSettingsTileColors
|
||||
import com.alorma.compose.settings.ui.base.internal.SettingsTileDefaults
|
||||
import com.kouros.data.R
|
||||
import com.kouros.navigation.utils.getSettingsViewModel
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun DisplaySettings(context: Context, navigateBack: () -> Unit) {
|
||||
Scaffold(
|
||||
topBar = {
|
||||
CenterAlignedTopAppBar(
|
||||
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),
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
},
|
||||
) { padding ->
|
||||
val scrollState = rememberScrollState()
|
||||
Column(
|
||||
modifier =
|
||||
Modifier
|
||||
.consumeWindowInsets(padding)
|
||||
.verticalScroll(scrollState)
|
||||
.padding(top = padding.calculateTopPadding()),
|
||||
) {
|
||||
DisplaySettings(context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
private fun DisplaySettings(context: Context) {
|
||||
val settingsViewModel = getSettingsViewModel(context)
|
||||
Section(title = "Anzeige") {
|
||||
val state = remember {
|
||||
mutableStateOf(
|
||||
settingsViewModel.threedBuilding.value
|
||||
)
|
||||
}
|
||||
SettingsCheckbox(
|
||||
state = state.value,
|
||||
title = { Text(text = stringResource(R.string.threed_building)) },
|
||||
onCheckedChange = {
|
||||
state.value = it
|
||||
settingsViewModel.onThreedBuildingChanged(it)
|
||||
},
|
||||
)
|
||||
}
|
||||
Section(title = "Dunkles Design") {
|
||||
val state = remember {
|
||||
mutableIntStateOf(
|
||||
settingsViewModel.darkMode.value
|
||||
)
|
||||
}
|
||||
DarkModeData(context).darkDesign.forEach { sampleItem ->
|
||||
SettingsRadioButton(
|
||||
state = state.intValue == sampleItem.key,
|
||||
title = { Text(text = sampleItem.title) },
|
||||
onClick = {
|
||||
state.intValue = sampleItem.key
|
||||
settingsViewModel.onDarkModeChanged(state.intValue)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun Section(
|
||||
title: String,
|
||||
enabled: Boolean = true,
|
||||
verticalArrangement: Arrangement.Vertical = Arrangement.spacedBy(4.dp),
|
||||
content: @Composable ColumnScope.() -> Unit,
|
||||
) {
|
||||
SettingsGroup(
|
||||
contentPadding = PaddingValues(0.dp),
|
||||
verticalArrangement = verticalArrangement,
|
||||
enabled = enabled,
|
||||
title = { Text(text = title) },
|
||||
) {
|
||||
Card(
|
||||
colors = CardDefaults.cardColors(
|
||||
containerColor = (LocalSettingsTileColors.current
|
||||
?: SettingsTileDefaults.colors()).containerColor
|
||||
),
|
||||
) {
|
||||
content()
|
||||
}
|
||||
}
|
||||
}
|
||||
internal class DarkModeData(context: Context) {
|
||||
val darkDesign =
|
||||
listOf(
|
||||
Item(
|
||||
key = 0,
|
||||
title = context.getString(R.string.off_action_title),
|
||||
),
|
||||
Item(
|
||||
key = 1,
|
||||
title = context.getString(R.string.on_action_title),
|
||||
),
|
||||
Item(
|
||||
key = 2,
|
||||
title = context.getString(R.string.use_telephon_settings),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
internal data class Item(
|
||||
val key: Int,
|
||||
val title: String,
|
||||
)
|
||||
@@ -0,0 +1,130 @@
|
||||
package com.kouros.navigation.ui.settings
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.consumeWindowInsets
|
||||
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.CenterAlignedTopAppBar
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation.NavHostController
|
||||
import com.kouros.data.R
|
||||
import com.kouros.navigation.data.RouteEngine
|
||||
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
|
||||
fun NavigationScreen(viewModel: SettingsViewModel, navigateBack: () -> Unit) {
|
||||
|
||||
NavigationTheme(useDarkTheme = viewModel.darkMode.collectAsState().value == 1) {
|
||||
Scaffold(
|
||||
topBar = {
|
||||
CenterAlignedTopAppBar(
|
||||
title = {
|
||||
Text(
|
||||
stringResource(id = R.string.navigation_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),
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
},
|
||||
) { padding ->
|
||||
val scrollState = rememberScrollState()
|
||||
Column(
|
||||
modifier =
|
||||
Modifier
|
||||
.consumeWindowInsets(padding)
|
||||
.verticalScroll(scrollState)
|
||||
.padding(top = padding.calculateTopPadding()),
|
||||
) {
|
||||
NavigationSettings(viewModel)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun NavigationSettings(viewModel: SettingsViewModel) {
|
||||
val avoidMotorway by viewModel.avoidMotorway.collectAsState()
|
||||
val avoidTollway by viewModel.avoidTollway.collectAsState()
|
||||
val carLocation by viewModel.carLocation.collectAsState()
|
||||
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
|
||||
)
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
SectionTitle(stringResource(R.string.routing_engine))
|
||||
|
||||
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 = {
|
||||
key = it
|
||||
viewModel::onTomTomApiKeyChanged
|
||||
},
|
||||
label = { Text(stringResource(R.string.tomtom_api_key)) },
|
||||
textStyle = TextStyle(color = Color.Green, fontWeight = FontWeight.Bold),
|
||||
modifier = Modifier.padding(20.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,151 +0,0 @@
|
||||
package com.kouros.navigation.ui.settings
|
||||
|
||||
import android.content.Context
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.consumeWindowInsets
|
||||
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.CenterAlignedTopAppBar
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.alorma.compose.settings.ui.SettingsCheckbox
|
||||
import com.alorma.compose.settings.ui.SettingsRadioButton
|
||||
import com.kouros.data.R
|
||||
import com.kouros.navigation.data.Constants
|
||||
import com.kouros.navigation.data.Constants.ROUTING_ENGINE
|
||||
import com.kouros.navigation.data.RouteEngine
|
||||
import com.kouros.navigation.utils.NavigationUtils
|
||||
import com.kouros.navigation.utils.getSettingsViewModel
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun NavigationScreenSettings(context: Context, navigateBack: () -> Unit) {
|
||||
Scaffold(
|
||||
topBar = {
|
||||
CenterAlignedTopAppBar(
|
||||
title = {
|
||||
Text(
|
||||
stringResource(id = R.string.navigation_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),
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
},
|
||||
) { padding ->
|
||||
val scrollState = rememberScrollState()
|
||||
Column(
|
||||
modifier =
|
||||
Modifier
|
||||
.consumeWindowInsets(padding)
|
||||
.verticalScroll(scrollState)
|
||||
.padding(top = padding.calculateTopPadding()),
|
||||
) {
|
||||
NavigationSettings(context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun NavigationSettings(context: Context) {
|
||||
val settingsViewModel = getSettingsViewModel(context)
|
||||
Section(title = stringResource(id = R.string.options)) {
|
||||
val avoidMotorwayState = remember {
|
||||
mutableStateOf(
|
||||
settingsViewModel.avoidMotorway.value
|
||||
)
|
||||
}
|
||||
SettingsCheckbox(
|
||||
state = avoidMotorwayState.value,
|
||||
title = { Text(text = stringResource(id = R.string.avoid_highways_row_title)) },
|
||||
onCheckedChange = {
|
||||
avoidMotorwayState.value = it
|
||||
settingsViewModel.onAvoidMotorway(it)
|
||||
},
|
||||
)
|
||||
|
||||
val avoidTollwayState = remember {
|
||||
mutableStateOf(
|
||||
settingsViewModel.avoidTollway.value
|
||||
)
|
||||
}
|
||||
SettingsCheckbox(
|
||||
state = avoidTollwayState.value,
|
||||
title = { Text(text = stringResource(id = R.string.avoid_tolls_row_title)) },
|
||||
onCheckedChange = {
|
||||
avoidTollwayState.value = it
|
||||
settingsViewModel.onAvoidTollway(it)
|
||||
},
|
||||
)
|
||||
|
||||
val carLocationState = remember {
|
||||
mutableStateOf(
|
||||
settingsViewModel.carLocation.value
|
||||
)
|
||||
}
|
||||
SettingsCheckbox(
|
||||
state = carLocationState.value,
|
||||
title = { Text(text = stringResource(id = R.string.use_car_location)) },
|
||||
onCheckedChange = {
|
||||
carLocationState.value = it
|
||||
settingsViewModel.onCarLocation(it)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
Section(title = stringResource(id = R.string.routing_engine)) {
|
||||
val state = remember {
|
||||
mutableIntStateOf(
|
||||
settingsViewModel.routingEngine.value
|
||||
)
|
||||
}
|
||||
RoutingEngineData.engines.forEach { sampleItem ->
|
||||
SettingsRadioButton(
|
||||
state = state.intValue == sampleItem.key,
|
||||
title = { Text(text = sampleItem.title) },
|
||||
onClick = {
|
||||
state.intValue = sampleItem.key
|
||||
settingsViewModel.onRoutingEngineChanged(state.intValue)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal object RoutingEngineData {
|
||||
val engines =
|
||||
listOf(
|
||||
Item(
|
||||
key = 0,
|
||||
title = RouteEngine.VALHALLA.toString(),
|
||||
),
|
||||
Item(
|
||||
key = 1,
|
||||
title = RouteEngine.OSRM.toString(),
|
||||
),
|
||||
Item(
|
||||
key = 2,
|
||||
title = RouteEngine.TOMTOM.toString(),
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -12,7 +12,7 @@ import com.kouros.navigation.model.SettingsViewModel
|
||||
import com.kouros.navigation.repository.SettingsRepository
|
||||
|
||||
@Composable
|
||||
fun SettingsRoute(route: String, navController: NavHostController, function: () -> Boolean) {
|
||||
fun SettingsRoute(route: String, navController: NavHostController, function: () -> Unit) {
|
||||
|
||||
val context = LocalContext.current
|
||||
|
||||
@@ -28,10 +28,12 @@ fun SettingsRoute(route: String, navController: NavHostController, function: ()
|
||||
}
|
||||
)
|
||||
if (route == "display_settings") {
|
||||
SettingsScreen(viewModel = viewModel)
|
||||
DisplayScreen(viewModel = viewModel, function)
|
||||
}
|
||||
if (route == "nav_settings") {
|
||||
SettingsScreen(viewModel = viewModel)
|
||||
NavigationScreen (viewModel = viewModel, function)
|
||||
}
|
||||
if (route == "settings") {
|
||||
SettingsScreen(viewModel, navController, function)
|
||||
}
|
||||
///DisplaySettings(context, viewModel, navController.popBackStack())
|
||||
}
|
||||
|
||||
@@ -1,151 +1,72 @@
|
||||
package com.kouros.navigation.ui.settings
|
||||
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.consumeWindowInsets
|
||||
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.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
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
|
||||
fun SettingsScreen(viewModel: SettingsViewModel) {
|
||||
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)) {
|
||||
|
||||
val darkMode by viewModel.darkMode.collectAsState()
|
||||
val threedBuilding by viewModel.threedBuilding.collectAsState()
|
||||
val avoidMotorway by viewModel.avoidMotorway.collectAsState()
|
||||
val avoidTollway by viewModel.avoidTollway.collectAsState()
|
||||
val carLocation by viewModel.carLocation.collectAsState()
|
||||
val routingEngine by viewModel.routingEngine.collectAsState()
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
CenterAlignedTopAppBar(
|
||||
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),
|
||||
// )
|
||||
// }
|
||||
},
|
||||
)
|
||||
},
|
||||
)
|
||||
{ padding ->
|
||||
val scrollState = rememberScrollState()
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(top = 20.dp)
|
||||
.verticalScroll(scrollState)
|
||||
) {
|
||||
|
||||
Text(
|
||||
text = stringResource(R.string.settings_action_title),
|
||||
style = MaterialTheme.typography.headlineMedium
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
|
||||
// Appearance
|
||||
SectionTitle(stringResource(R.string.threed_building))
|
||||
|
||||
SettingSwitch(
|
||||
title = stringResource(R.string.threed_building),
|
||||
checked = threedBuilding,
|
||||
onCheckedChange = viewModel::onThreedBuildingChanged
|
||||
)
|
||||
|
||||
SectionTitle(stringResource(R.string.dark_mode))
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
// Appearance
|
||||
SectionTitle(stringResource(R.string.navigation_settings))
|
||||
|
||||
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.use_car_location),
|
||||
checked = carLocation,
|
||||
onCheckedChange = viewModel::onCarLocation
|
||||
)
|
||||
|
||||
SectionTitle(stringResource(R.string.routing_engine))
|
||||
|
||||
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
|
||||
)
|
||||
Button(onClick = { navController.navigate("display_settings") }) {
|
||||
Text(stringResource(R.string.display_settings))
|
||||
}
|
||||
Button(onClick = { navController.navigate("nav_settings") }) {
|
||||
Text(stringResource(R.string.navigation_settings))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user