move main view out of main activity

This commit is contained in:
Owen LeJeune
2022-02-10 16:35:17 -05:00
parent 907c416d48
commit ce8efd7eea
8 changed files with 126 additions and 105 deletions

View File

@@ -37,110 +37,10 @@ class MainActivity : ComponentActivity() {
@Composable
fun MyApp() {
TVTimeTheme {
val appNavController = rememberNavController()
Box {
MainNavigationRoutes(navController = appNavController)
}
}
}
@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(
title = { Text(text = title.value) },
scrollBehavior = scrollBehavior
)
}
@Composable
private fun BottomNavBar(navController: NavController, appBarTitle: MutableState<String>) {
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry?.destination?.route
NavigationBar {
BottomNavItem.Items.forEach { item ->
NavigationBarItem(
icon = { Icon(painter = painterResource(id = item.icon), contentDescription = null) },
label = { Text(item.name) },
selected = currentRoute == item.route,
onClick = {
onBottomAppBarItemClicked(
navController = navController,
appBarTitle = appBarTitle,
item = item
)
}
)
}
}
}
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
}
}
@Composable
private fun SearchFab() {
val context = LocalContext.current
FloatingActionButton(onClick = {
Toast.makeText(context, "Search Clicked!", Toast.LENGTH_SHORT).show()
}) {
Icon(Icons.Filled.Search, "")
}
}

View File

@@ -11,6 +11,10 @@ import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyVerticalGrid
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Card
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Search
import androidx.compose.material3.FloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@@ -144,4 +148,20 @@ fun TopLevelSwitchPreview() {
TopLevelSwitch("This is a switch") { isChecked ->
Toast.makeText(context, "Switch changed to $isChecked", Toast.LENGTH_SHORT).show()
}
}
@Composable
fun SearchFab() {
val context = LocalContext.current
FloatingActionButton(onClick = {
Toast.makeText(context, "Search Clicked!", Toast.LENGTH_SHORT).show()
}) {
Icon(Icons.Filled.Search, "")
}
}
@Preview
@Composable
fun SearchFabPreview() {
SearchFab()
}

View File

@@ -4,11 +4,7 @@ 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
import com.owenlejeune.tvtime.ui.screens.*
@Composable
fun MainNavigationRoutes(navController: NavHostController) {

View File

@@ -0,0 +1,105 @@
package com.owenlejeune.tvtime.ui.screens
import androidx.compose.animation.rememberSplineBasedDecay
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Scaffold
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.res.painterResource
import androidx.navigation.NavController
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import com.owenlejeune.tvtime.ui.components.SearchFab
import com.owenlejeune.tvtime.ui.navigation.BottomNavItem
import com.owenlejeune.tvtime.ui.navigation.BottomNavigationRoutes
@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(
title = { Text(text = title.value) },
scrollBehavior = scrollBehavior
)
}
@Composable
private fun BottomNavBar(navController: NavController, appBarTitle: MutableState<String>) {
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry?.destination?.route
NavigationBar {
BottomNavItem.Items.forEach { item ->
NavigationBarItem(
icon = { Icon(painter = painterResource(id = item.icon), contentDescription = null) },
label = { Text(item.name) },
selected = currentRoute == item.route,
onClick = {
onBottomAppBarItemClicked(
navController = navController,
appBarTitle = appBarTitle,
item = item
)
}
)
}
}
}
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
}
}