Implement a navigation system
This commit is contained in:
@@ -4,21 +4,36 @@ import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.activity.viewModels
|
||||
import org.nsh07.pomodoro.ui.AppScreen
|
||||
import org.nsh07.pomodoro.ui.NavItem
|
||||
import org.nsh07.pomodoro.ui.Screen
|
||||
import org.nsh07.pomodoro.ui.theme.TomatoTheme
|
||||
import org.nsh07.pomodoro.ui.viewModel.UiViewModel
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
val viewModel: UiViewModel by viewModels<UiViewModel>()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
setContent {
|
||||
TomatoTheme {
|
||||
AppScreen(viewModel)
|
||||
AppScreen()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val screens = listOf(
|
||||
NavItem(
|
||||
Screen.Timer,
|
||||
R.drawable.hourglass,
|
||||
R.drawable.hourglass_filled,
|
||||
"Timer"
|
||||
),
|
||||
NavItem(
|
||||
Screen.Settings,
|
||||
R.drawable.settings,
|
||||
R.drawable.settings_filled,
|
||||
"Settings"
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.nsh07.pomodoro.ui
|
||||
|
||||
import androidx.compose.animation.Crossfade
|
||||
import androidx.compose.foundation.layout.calculateEndPadding
|
||||
import androidx.compose.foundation.layout.calculateStartPadding
|
||||
import androidx.compose.foundation.layout.padding
|
||||
@@ -9,7 +10,6 @@ import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.ShortNavigationBar
|
||||
import androidx.compose.material3.ShortNavigationBarItem
|
||||
import androidx.compose.material3.ShortNavigationBarItemDefaults
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
@@ -22,18 +22,23 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.navigation3.runtime.entry
|
||||
import androidx.navigation3.runtime.entryProvider
|
||||
import androidx.navigation3.runtime.rememberNavBackStack
|
||||
import androidx.navigation3.ui.NavDisplay
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.nsh07.pomodoro.R
|
||||
import org.nsh07.pomodoro.MainActivity.Companion.screens
|
||||
import org.nsh07.pomodoro.ui.timerScreen.TimerScreen
|
||||
import org.nsh07.pomodoro.ui.viewModel.UiViewModel
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
|
||||
@Composable
|
||||
fun AppScreen(
|
||||
viewModel: UiViewModel,
|
||||
modifier: Modifier = Modifier
|
||||
modifier: Modifier = Modifier,
|
||||
viewModel: UiViewModel = viewModel()
|
||||
) {
|
||||
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
|
||||
val remainingTime by viewModel.time.collectAsStateWithLifecycle()
|
||||
@@ -50,31 +55,63 @@ fun AppScreen(
|
||||
|
||||
val layoutDirection = LocalLayoutDirection.current
|
||||
|
||||
val backStack = rememberNavBackStack<Screen>(Screen.Timer)
|
||||
|
||||
Scaffold(
|
||||
bottomBar = {
|
||||
ShortNavigationBar {
|
||||
ShortNavigationBarItem(
|
||||
selected = true,
|
||||
onClick = { },
|
||||
icon = { Icon(painterResource(R.drawable.hourglass_filled), null) },
|
||||
label = { Text("Timer") },
|
||||
colors = ShortNavigationBarItemDefaults.colors()
|
||||
)
|
||||
screens.forEach {
|
||||
val selected = backStack.last() == it.route
|
||||
ShortNavigationBarItem(
|
||||
selected = selected,
|
||||
onClick = if (it.route != Screen.Timer) {
|
||||
{
|
||||
if (backStack.size < 2) backStack.add(it.route)
|
||||
else backStack[1] = it.route
|
||||
}
|
||||
} else {
|
||||
{ if (backStack.size > 1) backStack.removeAt(1) }
|
||||
},
|
||||
icon = {
|
||||
Crossfade (selected) { selected ->
|
||||
if (selected) Icon(painterResource(it.selectedIcon), null)
|
||||
else Icon(painterResource(it.unselectedIcon), null)
|
||||
}
|
||||
},
|
||||
label = { Text(it.label) }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
) { contentPadding ->
|
||||
TimerScreen(
|
||||
uiState = uiState,
|
||||
showBrandTitle = showBrandTitle,
|
||||
progress = { progress },
|
||||
resetTimer = viewModel::resetTimer,
|
||||
skipTimer = viewModel::skipTimer,
|
||||
toggleTimer = viewModel::toggleTimer,
|
||||
modifier = modifier.padding(
|
||||
start = contentPadding.calculateStartPadding(layoutDirection),
|
||||
end = contentPadding.calculateEndPadding(layoutDirection),
|
||||
bottom = contentPadding.calculateBottomPadding()
|
||||
)
|
||||
NavDisplay(
|
||||
backStack = backStack,
|
||||
onBack = { backStack.removeLastOrNull() },
|
||||
entryProvider = entryProvider {
|
||||
entry<Screen.Timer> {
|
||||
TimerScreen(
|
||||
uiState = uiState,
|
||||
showBrandTitle = showBrandTitle,
|
||||
progress = { progress },
|
||||
resetTimer = viewModel::resetTimer,
|
||||
skipTimer = viewModel::skipTimer,
|
||||
toggleTimer = viewModel::toggleTimer,
|
||||
modifier = modifier.padding(
|
||||
start = contentPadding.calculateStartPadding(layoutDirection),
|
||||
end = contentPadding.calculateEndPadding(layoutDirection),
|
||||
bottom = contentPadding.calculateBottomPadding()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
entry<Screen.Settings> {
|
||||
Text("Settings")
|
||||
}
|
||||
|
||||
entry<Screen.Stats> {
|
||||
Text("Stats")
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
23
app/src/main/java/org/nsh07/pomodoro/ui/Screen.kt
Normal file
23
app/src/main/java/org/nsh07/pomodoro/ui/Screen.kt
Normal file
@@ -0,0 +1,23 @@
|
||||
package org.nsh07.pomodoro.ui
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.navigation3.runtime.NavKey
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
sealed class Screen: NavKey {
|
||||
@Serializable
|
||||
object Timer : Screen()
|
||||
@Serializable
|
||||
object Settings : Screen()
|
||||
@Serializable
|
||||
object Stats : Screen()
|
||||
}
|
||||
|
||||
data class NavItem(
|
||||
val route: Screen,
|
||||
@param:DrawableRes
|
||||
val unselectedIcon: Int,
|
||||
@param:DrawableRes
|
||||
val selectedIcon: Int,
|
||||
val label: String
|
||||
)
|
||||
Reference in New Issue
Block a user