Implements basic navigation
This commit is contained in:
parent
d6c93f262b
commit
c45d852aa0
10 changed files with 237 additions and 39 deletions
50
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
50
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="ComposePreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<option name="composableFile" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="ComposePreviewMustBeTopLevelFunction" enabled="true" level="ERROR" enabled_by_default="true">
|
||||||
|
<option name="composableFile" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="ComposePreviewNeedsComposableAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
|
||||||
|
<option name="composableFile" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="ComposePreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true">
|
||||||
|
<option name="composableFile" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="GlancePreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
|
||||||
|
<option name="composableFile" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="GlancePreviewMustBeTopLevelFunction" enabled="true" level="ERROR" enabled_by_default="true">
|
||||||
|
<option name="composableFile" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="GlancePreviewNeedsComposableAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
|
||||||
|
<option name="composableFile" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="GlancePreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true">
|
||||||
|
<option name="composableFile" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PreviewAnnotationInFunctionWithParameters" enabled="true" level="ERROR" enabled_by_default="true">
|
||||||
|
<option name="composableFile" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PreviewApiLevelMustBeValid" enabled="true" level="ERROR" enabled_by_default="true">
|
||||||
|
<option name="composableFile" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PreviewDeviceShouldUseNewSpec" enabled="true" level="WEAK WARNING" enabled_by_default="true">
|
||||||
|
<option name="composableFile" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PreviewFontScaleMustBeGreaterThanZero" enabled="true" level="ERROR" enabled_by_default="true">
|
||||||
|
<option name="composableFile" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PreviewMultipleParameterProviders" enabled="true" level="ERROR" enabled_by_default="true">
|
||||||
|
<option name="composableFile" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PreviewParameterProviderOnFirstParameter" enabled="true" level="ERROR" enabled_by_default="true">
|
||||||
|
<option name="composableFile" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
<inspection_tool class="PreviewPickerAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
|
||||||
|
<option name="composableFile" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
</profile>
|
||||||
|
</component>
|
||||||
|
|
@ -1,24 +1,44 @@
|
||||||
package com.dnsc.plaindo
|
package com.dnsc.plaindo
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.outlined.DateRange
|
||||||
|
import androidx.compose.material.icons.outlined.Home
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.navigation.compose.NavHost
|
import androidx.navigation.compose.NavHost
|
||||||
import androidx.navigation.compose.composable
|
import androidx.navigation.compose.composable
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
import com.dnsc.plaindo.ui.overview.PlaindoOverview
|
import com.dnsc.plaindo.ui.agenda.PlaindoAgendaScreen
|
||||||
|
import com.dnsc.plaindo.ui.components.BottomNavigation
|
||||||
|
import com.dnsc.plaindo.ui.components.TopBar
|
||||||
import com.dnsc.plaindo.ui.overview.PlaindoOverviewScreen
|
import com.dnsc.plaindo.ui.overview.PlaindoOverviewScreen
|
||||||
import com.dnsc.plaindo.ui.settings.PlaindoSettings
|
|
||||||
import com.dnsc.plaindo.ui.settings.PlaindoSettingsScreen
|
import com.dnsc.plaindo.ui.settings.PlaindoSettingsScreen
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun PlaindoApp() {
|
fun PlaindoApp() {
|
||||||
|
val topLevelRoutes = listOf(
|
||||||
|
TopLevelRoute("Home", "overview", Icons.Outlined.Home),
|
||||||
|
TopLevelRoute("Agenda", "agenda", Icons.Outlined.DateRange),
|
||||||
|
)
|
||||||
val navController = rememberNavController()
|
val navController = rememberNavController()
|
||||||
|
|
||||||
NavHost(navController, startDestination = PlaindoOverview) {
|
Scaffold(
|
||||||
composable<PlaindoOverview> {
|
topBar = {
|
||||||
PlaindoOverviewScreen()
|
TopBar("Plaindo", navController)
|
||||||
}
|
},
|
||||||
composable<PlaindoSettings> {
|
bottomBar = { BottomNavigation(navController, topLevelRoutes) }
|
||||||
PlaindoSettingsScreen()
|
) { innerPadding ->
|
||||||
|
NavHost(navController, startDestination = "overview") {
|
||||||
|
composable("overview") {
|
||||||
|
PlaindoOverviewScreen(navController, innerPadding)
|
||||||
|
}
|
||||||
|
composable("agenda") {
|
||||||
|
PlaindoAgendaScreen(innerPadding)
|
||||||
|
}
|
||||||
|
composable("settings") {
|
||||||
|
PlaindoSettingsScreen(innerPadding)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
6
app/src/main/java/com/dnsc/plaindo/TopLevelRoute.kt
Normal file
6
app/src/main/java/com/dnsc/plaindo/TopLevelRoute.kt
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
package com.dnsc.plaindo
|
||||||
|
|
||||||
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
|
|
||||||
|
data class TopLevelRoute(val name: String, val route: String, val icon: ImageVector)
|
||||||
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
package com.dnsc.plaindo.ui.agenda
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
object PlaindoAgenda
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.dnsc.plaindo.ui.agenda
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun PlaindoAgendaScreen(innerPadding: PaddingValues) {
|
||||||
|
Column(modifier = Modifier.padding(innerPadding)) {
|
||||||
|
Text(text = "Agenda")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
package com.dnsc.plaindo.ui.components
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.outlined.DateRange
|
||||||
|
import androidx.compose.material.icons.outlined.Home
|
||||||
|
import androidx.compose.material.icons.outlined.List
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.NavigationBar
|
||||||
|
import androidx.compose.material3.NavigationBarItem
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.navigation.NavDestination.Companion.hierarchy
|
||||||
|
import androidx.navigation.NavGraph.Companion.findStartDestination
|
||||||
|
import androidx.navigation.NavHostController
|
||||||
|
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||||
|
import com.dnsc.plaindo.TopLevelRoute
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun BottomNavigation(navController: NavHostController, topLevelRoutes: List<TopLevelRoute>) {
|
||||||
|
NavigationBar {
|
||||||
|
val navBackStackEntry = navController.currentBackStackEntryAsState().value
|
||||||
|
val currentDestination = navBackStackEntry?.destination
|
||||||
|
|
||||||
|
topLevelRoutes.forEach { topLevelRoute ->
|
||||||
|
NavigationBarItem(
|
||||||
|
icon = { Icon(topLevelRoute.icon, contentDescription = topLevelRoute.name) },
|
||||||
|
label = { Text(topLevelRoute.name) },
|
||||||
|
selected = currentDestination?.hierarchy?.any { it.route == topLevelRoute.route } == true,
|
||||||
|
onClick = {
|
||||||
|
navController.navigate(topLevelRoute.route) {
|
||||||
|
popUpTo(navController.graph.findStartDestination().id) {
|
||||||
|
saveState = true
|
||||||
|
}
|
||||||
|
launchSingleTop = true
|
||||||
|
restoreState = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,23 +1,30 @@
|
||||||
package com.dnsc.plaindo.ui.shared
|
package com.dnsc.plaindo.ui.components
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.material3.TopAppBar
|
import androidx.compose.material3.TopAppBar
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.navigation.NavController
|
||||||
|
import androidx.navigation.NavHostController
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun TopBar(title: String) {
|
fun TopBar(title: String, navController: NavHostController) {
|
||||||
TopAppBar(
|
TopAppBar(
|
||||||
title = {
|
title = {
|
||||||
Text(
|
Text(
|
||||||
text = title,
|
text = title,
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth().padding(start = 12.dp),
|
||||||
textAlign = TextAlign.Left
|
textAlign = TextAlign.Left
|
||||||
)
|
)
|
||||||
|
},
|
||||||
|
actions = {
|
||||||
|
TopBarMenu(navController)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
package com.dnsc.plaindo.ui.components
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.filled.MoreVert
|
||||||
|
import androidx.compose.material.icons.outlined.Menu
|
||||||
|
import androidx.compose.material.icons.outlined.Search
|
||||||
|
import androidx.compose.material.icons.outlined.Settings
|
||||||
|
import androidx.compose.material3.DropdownMenu
|
||||||
|
import androidx.compose.material3.DropdownMenuItem
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
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.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import androidx.navigation.NavController
|
||||||
|
import androidx.navigation.NavGraph.Companion.findStartDestination
|
||||||
|
import androidx.navigation.NavHostController
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun TopBarMenu(navController: NavHostController) {
|
||||||
|
var expanded by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(16.dp)
|
||||||
|
) {
|
||||||
|
IconButton(onClick = { expanded = !expanded }) {
|
||||||
|
Icon(Icons.Default.MoreVert, contentDescription = "More options")
|
||||||
|
}
|
||||||
|
DropdownMenu(
|
||||||
|
expanded = expanded,
|
||||||
|
onDismissRequest = { expanded = false }
|
||||||
|
) {
|
||||||
|
DropdownMenuItem(
|
||||||
|
leadingIcon = { Icon(Icons.Outlined.Menu, contentDescription = "Filter", modifier = Modifier.padding(start = 12.dp)) },
|
||||||
|
text = { Text("Filter", fontSize = 16.sp, modifier = Modifier.padding(end = 16.dp)) },
|
||||||
|
onClick = { /* Do something... */ }
|
||||||
|
)
|
||||||
|
DropdownMenuItem(
|
||||||
|
leadingIcon = { Icon(Icons.Outlined.Search, contentDescription = "Search", modifier = Modifier.padding(start = 12.dp)) },
|
||||||
|
text = { Text("Search", fontSize = 16.sp, modifier = Modifier.padding(end = 16.dp)) },
|
||||||
|
onClick = { /* Do something... */ }
|
||||||
|
)
|
||||||
|
DropdownMenuItem(
|
||||||
|
leadingIcon = { Icon(Icons.Outlined.Settings, contentDescription = "Settings", modifier = Modifier.padding(start = 12.dp)) },
|
||||||
|
text = { Text("Settings", fontSize = 16.sp, modifier = Modifier.padding(end = 16.dp)) },
|
||||||
|
onClick = {
|
||||||
|
navController.navigate("settings") {
|
||||||
|
popUpTo(navController.graph.findStartDestination().id) {
|
||||||
|
saveState = true
|
||||||
|
}
|
||||||
|
launchSingleTop = true
|
||||||
|
restoreState = true
|
||||||
|
}
|
||||||
|
expanded = false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,24 +1,17 @@
|
||||||
package com.dnsc.plaindo.ui.overview
|
package com.dnsc.plaindo.ui.overview
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import com.dnsc.plaindo.ui.shared.TopBar
|
import androidx.navigation.NavHostController
|
||||||
|
import com.dnsc.plaindo.ui.components.TopBar
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun PlaindoOverviewScreen() {
|
fun PlaindoOverviewScreen(navController: NavHostController, innerPadding: PaddingValues) {
|
||||||
Scaffold(
|
Column(modifier = Modifier.padding(innerPadding)) {
|
||||||
topBar = {
|
Text(text = "Overview")
|
||||||
TopBar(title = "Overview")
|
|
||||||
}
|
|
||||||
) { innerPadding ->
|
|
||||||
Column(
|
|
||||||
modifier = Modifier.padding(innerPadding)
|
|
||||||
) {
|
|
||||||
Text(text = "Overview")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,15 @@
|
||||||
package com.dnsc.plaindo.ui.settings
|
package com.dnsc.plaindo.ui.settings
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import com.dnsc.plaindo.ui.shared.TopBar
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun PlaindoSettingsScreen() {
|
fun PlaindoSettingsScreen(innerPadding: PaddingValues) {
|
||||||
Scaffold(
|
Column(modifier = Modifier.padding(innerPadding)) {
|
||||||
topBar = {
|
Text(text = "Settings")
|
||||||
TopBar(title = "Settings")
|
|
||||||
}
|
|
||||||
) { innerPadding ->
|
|
||||||
Column(
|
|
||||||
modifier = Modifier.padding(innerPadding)
|
|
||||||
) {
|
|
||||||
Text(text = "Settings")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Reference in a new issue