mirror of
https://github.com/owenlejeune/TVTime.git
synced 2025-11-22 19:50:54 -05:00
refactor navigation code
This commit is contained in:
@@ -18,16 +18,11 @@ import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import com.owenlejeune.tvtime.ui.components.NavItems
|
||||
import com.owenlejeune.tvtime.ui.screens.FavouritesTab
|
||||
import com.owenlejeune.tvtime.ui.screens.MoviesTab
|
||||
import com.owenlejeune.tvtime.ui.screens.SettingsTab
|
||||
import com.owenlejeune.tvtime.ui.screens.TvTab
|
||||
import com.owenlejeune.tvtime.ui.navigation.BottomNavItem
|
||||
import com.owenlejeune.tvtime.ui.navigation.BottomNavigationRoutes
|
||||
import com.owenlejeune.tvtime.ui.navigation.MainNavigationRoutes
|
||||
import com.owenlejeune.tvtime.ui.theme.TVTimeTheme
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
@@ -39,49 +34,58 @@ class MainActivity : ComponentActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun MyApp() {
|
||||
TVTimeTheme {
|
||||
val navController = rememberNavController()
|
||||
val appBarTitle = remember { mutableStateOf(NavItems.Items[0].name) }
|
||||
val decayAnimationSpec = rememberSplineBasedDecay<Float>()
|
||||
val scrollBehavior = remember(decayAnimationSpec) {
|
||||
TopAppBarDefaults.exitUntilCollapsedScrollBehavior(decayAnimationSpec)
|
||||
|
||||
val appNavController = rememberNavController()
|
||||
Box {
|
||||
MainNavigationRoutes(navController = appNavController)
|
||||
}
|
||||
|
||||
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
||||
val currentRoute = navBackStackEntry?.destination?.route
|
||||
|
||||
Scaffold(
|
||||
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
backgroundColor = MaterialTheme.colorScheme.background,
|
||||
bottomBar = {
|
||||
BottomNavBar(
|
||||
navController = navController,
|
||||
appBarTitle = appBarTitle
|
||||
)
|
||||
},
|
||||
topBar = {
|
||||
TopBar(
|
||||
title = appBarTitle,
|
||||
scrollBehavior = scrollBehavior
|
||||
)
|
||||
},
|
||||
floatingActionButton = {
|
||||
if (currentRoute in listOf(NavItems.Movies.route, NavItems.TV.route)) {
|
||||
SearchFab()
|
||||
}
|
||||
}
|
||||
) { innerPadding ->
|
||||
Box(modifier = Modifier.padding(innerPadding)) {
|
||||
NavigationRoutes(navController = navController)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun MainAppView(appNavController: NavController) {
|
||||
val navController = rememberNavController()
|
||||
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
||||
val currentRoute = navBackStackEntry?.destination?.route
|
||||
|
||||
val appBarTitle = remember { mutableStateOf(BottomNavItem.Items[0].name) }
|
||||
val decayAnimationSpec = rememberSplineBasedDecay<Float>()
|
||||
val scrollBehavior = remember(decayAnimationSpec) {
|
||||
TopAppBarDefaults.exitUntilCollapsedScrollBehavior(decayAnimationSpec)
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
backgroundColor = MaterialTheme.colorScheme.background,
|
||||
bottomBar = {
|
||||
BottomNavBar(
|
||||
navController = navController,
|
||||
appBarTitle = appBarTitle
|
||||
)
|
||||
},
|
||||
topBar = {
|
||||
TopBar(
|
||||
title = appBarTitle,
|
||||
scrollBehavior = scrollBehavior
|
||||
)
|
||||
},
|
||||
floatingActionButton = {
|
||||
if (currentRoute in listOf(BottomNavItem.Movies.route, BottomNavItem.TV.route)) {
|
||||
SearchFab()
|
||||
}
|
||||
}
|
||||
) { innerPadding ->
|
||||
Box(modifier = Modifier.padding(innerPadding)) {
|
||||
BottomNavigationRoutes(navController = navController)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TopBar(title: MutableState<String>, scrollBehavior: TopAppBarScrollBehavior) {
|
||||
LargeTopAppBar(
|
||||
@@ -96,43 +100,37 @@ private fun BottomNavBar(navController: NavController, appBarTitle: MutableState
|
||||
val currentRoute = navBackStackEntry?.destination?.route
|
||||
|
||||
NavigationBar {
|
||||
NavItems.Items.forEachIndexed { index, item ->
|
||||
BottomNavItem.Items.forEach { item ->
|
||||
NavigationBarItem(
|
||||
icon = { Icon(painter = painterResource(id = item.icon), contentDescription = null) },
|
||||
label = { Text(item.name) },
|
||||
selected = currentRoute == item.route,
|
||||
onClick = {
|
||||
appBarTitle.value = item.name
|
||||
navController.navigate(item.route) {
|
||||
navController.graph.startDestinationRoute?.let { screenRoute ->
|
||||
popUpTo(screenRoute) {
|
||||
saveState = true
|
||||
}
|
||||
}
|
||||
launchSingleTop = true
|
||||
restoreState = true
|
||||
}
|
||||
onBottomAppBarItemClicked(
|
||||
navController = navController,
|
||||
appBarTitle = appBarTitle,
|
||||
item = item
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun NavigationRoutes(navController: NavHostController) {
|
||||
NavHost(navController = navController, startDestination = NavItems.Movies.route) {
|
||||
composable(NavItems.Movies.route) {
|
||||
MoviesTab()
|
||||
}
|
||||
composable(NavItems.TV.route) {
|
||||
TvTab()
|
||||
}
|
||||
composable(NavItems.Favourites.route) {
|
||||
FavouritesTab()
|
||||
}
|
||||
composable(NavItems.Settings.route) {
|
||||
SettingsTab()
|
||||
private fun onBottomAppBarItemClicked(
|
||||
navController: NavController,
|
||||
appBarTitle: MutableState<String>,
|
||||
item: BottomNavItem
|
||||
) {
|
||||
appBarTitle.value = item.name
|
||||
navController.navigate(item.route) {
|
||||
navController.graph.startDestinationRoute?.let { screenRoute ->
|
||||
popUpTo(screenRoute) {
|
||||
saveState = true
|
||||
}
|
||||
}
|
||||
launchSingleTop = true
|
||||
restoreState = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
package com.owenlejeune.tvtime.ui.components
|
||||
|
||||
import com.owenlejeune.tvtime.R
|
||||
|
||||
sealed class NavItems(val name: String, val icon: Int, val route: String) {
|
||||
|
||||
companion object {
|
||||
val Items = listOf(Movies, TV, Favourites, Settings)
|
||||
}
|
||||
|
||||
object Movies: NavItems("Movies", R.drawable.ic_movie, "movies_route")
|
||||
object TV: NavItems("TV", R.drawable.ic_tv, "tv_route")
|
||||
object Favourites: NavItems("Favourites", R.drawable.ic_favorite, "favourites_route")
|
||||
object Settings: NavItems("Settings", R.drawable.ic_settings, "settings_route")
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.owenlejeune.tvtime.ui.navigation
|
||||
|
||||
import com.owenlejeune.tvtime.R
|
||||
|
||||
sealed class BottomNavItem(val name: String, val icon: Int, val route: String) {
|
||||
|
||||
companion object {
|
||||
val Items = listOf(Movies, TV, Favourites, Settings)
|
||||
}
|
||||
|
||||
object Movies: BottomNavItem("Movies", R.drawable.ic_movie, "movies_route")
|
||||
object TV: BottomNavItem("TV", R.drawable.ic_tv, "tv_route")
|
||||
object Favourites: BottomNavItem("Favourites", R.drawable.ic_favorite, "favourites_route")
|
||||
object Settings: BottomNavItem("Settings", R.drawable.ic_settings, "settings_route")
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.owenlejeune.tvtime.ui.navigation
|
||||
|
||||
sealed class MainNavItem(val route: String) {
|
||||
|
||||
object MainView: MainNavItem("main_route")
|
||||
object DetailView: MainNavItem("detail_route")
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.owenlejeune.tvtime.ui.navigation
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import com.owenlejeune.tvtime.MainAppView
|
||||
import com.owenlejeune.tvtime.ui.screens.FavouritesTab
|
||||
import com.owenlejeune.tvtime.ui.screens.MoviesTab
|
||||
import com.owenlejeune.tvtime.ui.screens.SettingsTab
|
||||
import com.owenlejeune.tvtime.ui.screens.TvTab
|
||||
|
||||
@Composable
|
||||
fun MainNavigationRoutes(navController: NavHostController) {
|
||||
NavHost(navController = navController, startDestination = MainNavItem.MainView.route) {
|
||||
composable(MainNavItem.MainView.route) {
|
||||
MainAppView(appNavController = navController)
|
||||
}
|
||||
composable(MainNavItem.DetailView.route) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun BottomNavigationRoutes(navController: NavHostController) {
|
||||
NavHost(navController = navController, startDestination = BottomNavItem.Movies.route) {
|
||||
composable(BottomNavItem.Movies.route) {
|
||||
MoviesTab()
|
||||
}
|
||||
composable(BottomNavItem.TV.route) {
|
||||
TvTab()
|
||||
}
|
||||
composable(BottomNavItem.Favourites.route) {
|
||||
FavouritesTab()
|
||||
}
|
||||
composable(BottomNavItem.Settings.route) {
|
||||
SettingsTab()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user