Based on the following image, my App currently contains 2 main routes : Auth and Dashboard. When the user started the App, an observer will check whether the user is logged in and direct he/she to the Login Page/Dashboard.
From the image as you can see, I've set the NavGraph(which include all the Dashboard routes) in the MainActivity. The problem is when user click one of the bottom navigation items, he/she will be directed straight to the view page. Instead, what I wanted is to show the user the view inside the scaffold content of the Dashboard. Check the image below.
Based on the info, how can I get the composable view inside the scaffold content once the user click the item?
Any guidance will be much appreciated. Thanks!
Side Note: This is my first compose project and I am trying to implement the Single Activity architecture without any fragment used. I apologize prior if my code violate any design or programming convention as I am quite new into programming[self-learner aka Hobbyist here :( ].
MainActivity.kt
package com.example.firstcomposeproject
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.viewModels
import androidx.navigation.NavController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navigation
import com.example.firstcomposeproject.authview.FirebaseUserViewModel
import com.example.firstcomposeproject.authview.LogIn
import com.example.firstcomposeproject.authview.SignUpFragment
import com.example.firstcomposeproject.dashboard.*
import com.example.firstcomposeproject.ui.theme.FirstComposeProjectTheme
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val userViewModel: FirebaseUserViewModel by viewModels()
setContent {
FirstComposeProjectTheme(
darkTheme = false
) {
val navController = rememberNavController()
/*
Observing FirebaseUser LiveData to check if user is logged in. If yes, direct user
to dashboard, else direct user to authenticate screen.
*/
userViewModel.userMutableLiveData.observe(this, {
firebaseUser ->
if(firebaseUser != null){
navController.popBackStack()
navController.navigate("dashboard"){
popUpTo("auth"){
inclusive = true
}
}
userViewModel.clearFormField()
}else {
navController.navigate("auth"){
popUpTo("dashboard"){
inclusive = true
}
}
}
})
//Navigation Graph For The Whole App
NavHost(navController = navController, startDestination = "auth"){
navigation(startDestination = "logInUI", route = "auth"){
composable("logInUI"){
LogIn(
userViewModel,
onNavigate = {
navigateTo(it, navController)
}
).FinalView()
}
composable("signUpUI"){
SignUpFragment(
userViewModel,
onNavigate = {
navigateTo(it, navController)
}
).FinalView()
}
}
addDashBoardGraph(userViewModel, navController)
}
}
}
}
private fun navigateTo(
dest: String,
navController: NavController
){
navController.navigate(dest)
}
}
Dashboard.kt
package com.example.firstcomposeproject.dashboard
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.navigation.NavDestination.Companion.hierarchy
import androidx.navigation.NavGraph.Companion.findStartDestination
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.navigation
import com.example.firstcomposeproject.authview.FirebaseUserViewModel
import com.example.firstcomposeproject.dashboard.helper.Screen
import com.example.firstcomposeproject.ui.theme.Teal200
fun NavGraphBuilder.addDashBoardGraph(
userViewModel: FirebaseUserViewModel,
navController: NavHostController
) {
navigation(startDestination = "dashboardUI", route = "dashboard"){
composable("dashboardUI"){
Dashboard(
navController,
userViewModel
)
}
composable("navigationUI"){
Navigation()
}
composable("messageUI"){
Message()
}
composable("historyUI"){
History()
}
composable("profileUI"){
Profile(
userViewModel
)
}
}
}
@Composable
fun Dashboard(
navController: NavHostController,
userViewModel: FirebaseUserViewModel
){
val items = listOf(
Screen.Navigation,
Screen.Message,
Screen.History,
Screen.Profile
)
Scaffold(
bottomBar = {
BottomNavigation(
backgroundColor = Color.White,
contentColor = Teal200
) {
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentDestination = navBackStackEntry?.destination
items.forEach{ screen ->
BottomNavigationItem(
label = { Text(text = screen.label)},
selected = currentDestination?.hierarchy?.any{ it.route == screen.route } == true,
onClick = {
navController.navigate(screen.route)
{
popUpTo(navController.graph.findStartDestination().id) {
saveState = true
}
launchSingleTop = true
restoreState = true
}
},
icon = {
Icon(painterResource(id = screen.icon), screen.label)
}, unselectedContentColor = Color.Gray
)
}
}
}
){
//Scaffold Content - How to access the compose function from the MainActivity NavGraph here?
}
}