feat: add main nav host best practice
This commit is contained in:
@@ -36,9 +36,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
enableEdgeToEdge()
|
enableEdgeToEdge()
|
||||||
setContent {
|
setContent {
|
||||||
DrugTheme {
|
DrugTheme {
|
||||||
val navController = rememberNavController()
|
|
||||||
val snackbarHostState = remember { SnackbarHostState() }
|
|
||||||
val scope = rememberCoroutineScope()
|
|
||||||
AppNavGraph(
|
AppNavGraph(
|
||||||
// navController = navController,
|
// navController = navController,
|
||||||
// modifier = Modifier.padding(innerPadding)
|
// modifier = Modifier.padding(innerPadding)
|
||||||
|
|||||||
@@ -1,9 +1,18 @@
|
|||||||
package com.approagency.drug.navigation
|
package com.approagency.drug.navigation
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.navigation.NavType
|
||||||
import androidx.navigation.compose.NavHost
|
import androidx.navigation.compose.NavHost
|
||||||
import androidx.navigation.compose.composable
|
import androidx.navigation.compose.composable
|
||||||
|
import androidx.navigation.compose.navigation
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
|
import androidx.navigation.navArgument
|
||||||
|
import com.approagency.drug.presentation.screens.DrugDetailScreen
|
||||||
|
import com.approagency.drug.presentation.screens.HomeScreen
|
||||||
|
import com.approagency.drug.presentation.screens.LabScreen
|
||||||
|
import com.approagency.drug.presentation.screens.SearchScreen
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun AppNavGraph() {
|
fun AppNavGraph() {
|
||||||
@@ -12,12 +21,51 @@ fun AppNavGraph() {
|
|||||||
|
|
||||||
NavHost(
|
NavHost(
|
||||||
navController = navController,
|
navController = navController,
|
||||||
startDestination = "main_container"
|
startDestination = "home"
|
||||||
) {
|
) {
|
||||||
|
|
||||||
composable("main_container") {
|
// ───────────────
|
||||||
|
// BOTTOM TABS
|
||||||
|
// ───────────────
|
||||||
|
|
||||||
MainContainer()
|
composable("home") {
|
||||||
|
MainContainer(navController) {
|
||||||
|
HomeScreen(navController , modifier = Modifier)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
composable("search") {
|
||||||
|
MainContainer(navController) {
|
||||||
|
SearchScreen(navController)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
composable("lab") {
|
||||||
|
MainContainer(navController) {
|
||||||
|
LabScreen()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ───────────────
|
||||||
|
// GLOBAL SCREEN
|
||||||
|
// ───────────────
|
||||||
|
|
||||||
|
composable(
|
||||||
|
route = Screen.DrugDetail.route,
|
||||||
|
arguments = listOf(
|
||||||
|
navArgument("detailUrl") {
|
||||||
|
type = NavType.StringType
|
||||||
|
}
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
|
||||||
|
val detailUrl =
|
||||||
|
Uri.decode(it.arguments?.getString("detailUrl") ?: "")
|
||||||
|
|
||||||
|
DrugDetailScreen(
|
||||||
|
navController = navController,
|
||||||
|
detailUrl = detailUrl
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,61 +39,55 @@ import androidx.navigation.NavHostController
|
|||||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BottomBar(
|
fun BottomBar(navController: NavHostController) {
|
||||||
navController: NavHostController
|
|
||||||
) {
|
|
||||||
val items = listOf(
|
val items = listOf(
|
||||||
Triple(MainRoute.HomeGraph, "دارو", Icons.Default.Search),
|
Triple("home", "دارو", Icons.Default.Search),
|
||||||
Triple(MainRoute.SearchGraph, "سرچ", Icons.Rounded.Refresh),
|
Triple("search", "سرچ", Icons.Rounded.Refresh),
|
||||||
Triple(MainRoute.LabGraph, "آزمایش", Icons.Default.Build)
|
Triple("lab", "آزمایش", Icons.Default.Build)
|
||||||
)
|
)
|
||||||
|
|
||||||
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
||||||
val currentDestination = navBackStackEntry?.destination
|
val currentRoute = navBackStackEntry?.destination?.route
|
||||||
|
|
||||||
Surface(
|
Surface(
|
||||||
tonalElevation = 2.dp,
|
tonalElevation = 2.dp,
|
||||||
color = MaterialTheme.colorScheme.surface,
|
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.navigationBarsPadding()
|
.navigationBarsPadding()
|
||||||
.height(50.dp)
|
.height(56.dp)
|
||||||
) {
|
|
||||||
Row(
|
|
||||||
modifier = Modifier.fillMaxSize(),
|
|
||||||
verticalAlignment = Alignment.CenterVertically
|
|
||||||
) {
|
) {
|
||||||
|
Row(modifier = Modifier.fillMaxSize(),
|
||||||
|
verticalAlignment = Alignment.CenterVertically) {
|
||||||
|
|
||||||
items.forEach { item ->
|
items.forEach { item ->
|
||||||
|
|
||||||
val selected = currentDestination
|
val selected = currentRoute == item.first
|
||||||
?.hierarchy
|
|
||||||
?.any { it.route == item.first.route } == true
|
|
||||||
|
|
||||||
val color = if (selected)
|
val color = if (selected)
|
||||||
MaterialTheme.colorScheme.primary
|
MaterialTheme.colorScheme.primary
|
||||||
else
|
else
|
||||||
MaterialTheme.colorScheme.onSurfaceVariant
|
MaterialTheme.colorScheme.onSurfaceVariant
|
||||||
|
|
||||||
val background = if (selected)
|
val background = if (selected)
|
||||||
MaterialTheme.colorScheme.primary.copy(alpha = 0.12f)
|
MaterialTheme.colorScheme.primary.copy(alpha = 0.12f)
|
||||||
else
|
else
|
||||||
Color.Transparent
|
Color.Transparent
|
||||||
|
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f).padding(horizontal = 8.dp , vertical = 4.dp)
|
||||||
.padding(horizontal = 8.dp , vertical = 4.dp)
|
|
||||||
.clip(MaterialTheme.shapes.large)
|
.clip(MaterialTheme.shapes.large)
|
||||||
.background(background)
|
.background(background)
|
||||||
.clickable {
|
.clickable {
|
||||||
navController.navigate(item.first.route) {
|
if (!selected) {
|
||||||
popUpTo(navController.graph.findStartDestination().id) {
|
navController.navigate(item.first) {
|
||||||
|
popUpTo("home") {
|
||||||
saveState = true
|
saveState = true
|
||||||
}
|
}
|
||||||
launchSingleTop = true
|
launchSingleTop = true
|
||||||
restoreState = true
|
restoreState = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(horizontal = 10.dp, vertical = 10.dp),
|
}.padding(horizontal = 10.dp, vertical = 10.dp),
|
||||||
|
|
||||||
contentAlignment = Alignment.Center
|
contentAlignment = Alignment.Center
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
|||||||
@@ -1,51 +1,28 @@
|
|||||||
package com.approagency.drug.navigation
|
package com.approagency.drug.navigation
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.navigation.NavHostController
|
||||||
import androidx.navigation.compose.NavHost
|
import androidx.navigation.compose.NavHost
|
||||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||||
import androidx.navigation.compose.rememberNavController
|
|
||||||
import com.approagency.drug.navigation.graphs.homeGraph
|
|
||||||
import com.approagency.drug.navigation.graphs.labGraph
|
|
||||||
import com.approagency.drug.navigation.graphs.searchGraph
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun MainContainer() {
|
fun MainContainer(
|
||||||
|
navController: NavHostController,
|
||||||
|
content: @Composable () -> Unit
|
||||||
|
) {
|
||||||
|
|
||||||
val navController = rememberNavController()
|
|
||||||
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
|
||||||
|
|
||||||
val currentRoute = navBackStackEntry?.destination?.route
|
|
||||||
|
|
||||||
val showBottomBar = when (currentRoute) {
|
|
||||||
Screen.Home.route,
|
|
||||||
Screen.Search.route,
|
|
||||||
Screen.Lab.route -> true
|
|
||||||
else -> false
|
|
||||||
}
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
bottomBar = {
|
bottomBar = {
|
||||||
if (showBottomBar) {
|
|
||||||
BottomBar(navController)
|
BottomBar(navController)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
) { padding ->
|
) { padding ->
|
||||||
|
|
||||||
NavHost(
|
Box(modifier = Modifier.padding(padding)) {
|
||||||
navController = navController,
|
content()
|
||||||
startDestination = MainRoute.HomeGraph.route,
|
|
||||||
modifier =if (showBottomBar ) Modifier.padding(padding) else Modifier
|
|
||||||
|
|
||||||
) {
|
|
||||||
|
|
||||||
homeGraph(navController)
|
|
||||||
|
|
||||||
searchGraph(navController)
|
|
||||||
|
|
||||||
labGraph(navController)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,28 +1,19 @@
|
|||||||
package com.approagency.drug.navigation.graphs
|
//package com.approagency.drug.navigation.graphs
|
||||||
|
//
|
||||||
import androidx.compose.ui.Modifier
|
//import androidx.compose.ui.Modifier
|
||||||
import androidx.navigation.NavGraphBuilder
|
//import androidx.navigation.NavGraphBuilder
|
||||||
import androidx.navigation.NavHostController
|
//import androidx.navigation.NavHostController
|
||||||
import androidx.navigation.compose.composable
|
//import androidx.navigation.compose.composable
|
||||||
import androidx.navigation.navigation
|
//import androidx.navigation.navigation
|
||||||
import com.approagency.drug.navigation.MainRoute
|
//import com.approagency.drug.navigation.MainRoute
|
||||||
import com.approagency.drug.navigation.Screen
|
//import com.approagency.drug.navigation.Screen
|
||||||
import com.approagency.drug.presentation.screens.HomeScreen
|
//import com.approagency.drug.presentation.screens.HomeScreen
|
||||||
|
//
|
||||||
fun NavGraphBuilder.homeGraph(
|
//fun NavGraphBuilder.homeGraph(navController: NavHostController) {
|
||||||
navController: NavHostController
|
//
|
||||||
) {
|
// composable(MainRoute.HomeGraph.route) {
|
||||||
|
// HomeScreen(
|
||||||
navigation(
|
// navController = navController , modifier = Modifier
|
||||||
route = MainRoute.HomeGraph.route,
|
// )
|
||||||
startDestination = Screen.Home.route
|
// }
|
||||||
) {
|
//}
|
||||||
|
|
||||||
composable(Screen.Home.route) {
|
|
||||||
|
|
||||||
HomeScreen(
|
|
||||||
navController = navController , modifier = Modifier
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,25 +1,16 @@
|
|||||||
package com.approagency.drug.navigation.graphs
|
//package com.approagency.drug.navigation.graphs
|
||||||
|
//
|
||||||
import androidx.navigation.NavGraphBuilder
|
//import androidx.navigation.NavGraphBuilder
|
||||||
import androidx.navigation.NavHostController
|
//import androidx.navigation.NavHostController
|
||||||
import androidx.navigation.compose.composable
|
//import androidx.navigation.compose.composable
|
||||||
import androidx.navigation.navigation
|
//import androidx.navigation.navigation
|
||||||
import com.approagency.drug.navigation.MainRoute
|
//import com.approagency.drug.navigation.MainRoute
|
||||||
import com.approagency.drug.navigation.Screen
|
//import com.approagency.drug.navigation.Screen
|
||||||
import com.approagency.drug.presentation.screens.LabScreen
|
//import com.approagency.drug.presentation.screens.LabScreen
|
||||||
|
//
|
||||||
fun NavGraphBuilder.labGraph(
|
//fun NavGraphBuilder.labGraph(navController: NavHostController) {
|
||||||
navController: NavHostController
|
//
|
||||||
) {
|
// composable(MainRoute.LabGraph.route) {
|
||||||
|
// LabScreen()
|
||||||
navigation(
|
// }
|
||||||
route = MainRoute.LabGraph.route,
|
//}
|
||||||
startDestination = Screen.Lab.route
|
|
||||||
) {
|
|
||||||
|
|
||||||
composable(Screen.Lab.route) {
|
|
||||||
|
|
||||||
LabScreen()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,51 +1,20 @@
|
|||||||
package com.approagency.drug.navigation.graphs
|
//package com.approagency.drug.navigation.graphs
|
||||||
|
//
|
||||||
import android.net.Uri
|
//import android.net.Uri
|
||||||
import androidx.navigation.NavGraphBuilder
|
//import androidx.navigation.NavGraphBuilder
|
||||||
import androidx.navigation.NavHostController
|
//import androidx.navigation.NavHostController
|
||||||
import androidx.navigation.NavType
|
//import androidx.navigation.NavType
|
||||||
import androidx.navigation.compose.composable
|
//import androidx.navigation.compose.composable
|
||||||
import androidx.navigation.navArgument
|
//import androidx.navigation.navArgument
|
||||||
import androidx.navigation.navigation
|
//import androidx.navigation.navigation
|
||||||
import com.approagency.drug.navigation.MainRoute
|
//import com.approagency.drug.navigation.MainRoute
|
||||||
import com.approagency.drug.navigation.Screen
|
//import com.approagency.drug.navigation.Screen
|
||||||
import com.approagency.drug.presentation.screens.DrugDetailScreen
|
//import com.approagency.drug.presentation.screens.DrugDetailScreen
|
||||||
import com.approagency.drug.presentation.screens.SearchScreen
|
//import com.approagency.drug.presentation.screens.SearchScreen
|
||||||
|
//
|
||||||
fun NavGraphBuilder.searchGraph(
|
//fun NavGraphBuilder.searchGraph(navController: NavHostController) {
|
||||||
navController: NavHostController
|
//
|
||||||
) {
|
// composable(MainRoute.SearchGraph.route) {
|
||||||
|
// SearchScreen(navController)
|
||||||
navigation(
|
// }
|
||||||
route = MainRoute.SearchGraph.route,
|
//}
|
||||||
startDestination = Screen.Search.route
|
|
||||||
) {
|
|
||||||
|
|
||||||
composable(Screen.Search.route) {
|
|
||||||
|
|
||||||
SearchScreen(
|
|
||||||
navController = navController
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
composable(
|
|
||||||
route = Screen.DrugDetail.route,
|
|
||||||
arguments = listOf(
|
|
||||||
navArgument("detailUrl") {
|
|
||||||
type = NavType.StringType
|
|
||||||
}
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
|
|
||||||
val detailUrl =
|
|
||||||
Uri.decode(
|
|
||||||
it.arguments?.getString("detailUrl") ?: ""
|
|
||||||
)
|
|
||||||
|
|
||||||
DrugDetailScreen(
|
|
||||||
navController = navController,
|
|
||||||
detailUrl = detailUrl
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user