I am using jetpack compose navigation in my app but I get IllegalArgumentException while trying to navigate to geoMarkerScreen from homeScreen. The problem seems at the BottomNavigationBar...How can I resolve this? I laready set up the NavHost
package com.example.bettehomes.navigation
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.navigation.NavController
import androidx.navigation.compose.currentBackStackEntryAsState
@Composable
fun BottomNavigationBar(navController: NavController) {
NavigationBar {
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry?.destination?.route
BottomNavItem.values().forEach { item ->
NavigationBarItem(selected = currentRoute == item.route,
onClick = {
navController.navigate(item.route) {
popUpTo(navController.graph.startDestinationId) {
saveState = true
}
launchSingleTop = true
restoreState = true
}
}, icon = { Icon(item.icon, contentDescription = null) },label = { Text(item.label) })
}
}
}
The error appears to be at:
com.example.bettehomes.navigation.BottomNavigationBarKt$BottomNavigationBar$1$1$1.invoke(BottomNavigationBar.kt:23)
at com.example.bettehomes.navigation.BottomNavigationBarKt$BottomNavigationBar$1$1$1.invoke(BottomNavigationBar.kt:21)
NavHost.kt:
package com.example.bettehomes.navigation
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Scaffold
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.example.bettehomes.data.login.AuthViewModel
import com.example.bettehomes.presentation.GeoMarkerViewModel
import com.example.bettehomes.presentation.authscreens.HomeScreen
import com.example.bettehomes.presentation.authscreens.LoginScreen
import com.example.bettehomes.presentation.authscreens.PrivacyPolicyScreen
import com.example.bettehomes.presentation.authscreens.SignUpScreen
import com.example.bettehomes.presentation.authscreens.TermsAndConditionsScreen
import com.example.bettehomes.presentation.authscreens.settings.SettingsScreen
import com.example.bettehomes.presentation.authscreens.splash.SplashScreen
import com.example.bettehomes.presentation.mapscreens.GeoMarkerScreen
import com.example.bettehomes.presentation.mapscreens.MapsScreen
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun AppNavigation(
snackbarHostState: SnackbarHostState,
geoMarkerViewModel: GeoMarkerViewModel,
fetchLocationUpdates: () -> Unit,
authViewModel: AuthViewModel = hiltViewModel()
) {
val navController = rememberNavController()
val isAuthenticated by authViewModel.isAuthenticated.collectAsState()
Scaffold(
bottomBar = {
BottomNavigationBar(navController = navController)
}
) {it
NavHost(navController = navController, startDestination = Screens.SplashScreen) {
composable(Screens.SplashScreen) {
SplashScreen(openAndPopUp = { route, popUp ->
navController.navigateAndPopUp(route, popUp)
})
}
composable(Screens.HomeScreen) {
HomeScreen()
}
composable(Screens.MapScreen) {
MapsScreen(
snackbarHostState = snackbarHostState,
navController = navController,
fetchLocationUpdates = fetchLocationUpdates
)
}
composable(Screens.SignUpScreen) {
SignUpScreen(navController)
}
composable(Screens.LoginScreen) {
LoginScreen(navController)
}
composable(Screens.TermsAndConditions) {
TermsAndConditionsScreen(navController)
}
composable(Screens.PrivacyPolicy) {
PrivacyPolicyScreen(navController)
}
if (isAuthenticated) {
composable(Screens.GeoMarkerScreen) {
GeoMarkerScreen(geoMarkerViewModel, navController)
}
} else {
composable(Screens.LoginScreen) {
LoginScreen(navController)
}
}
composable(Screens.SettingsScreen) {
SettingsScreen(
restartApp = { route ->
navController.clearAndNavigate(
route,
startDestination = 1
)
},
openScreen = { route -> navController.navigate(route) }
)
}
}
}
}
BottomNavItem.kt:
package com.example.bettehomes.navigation
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.Search
import androidx.compose.material.icons.filled.Settings
import androidx.compose.ui.graphics.vector.ImageVector
enum class BottomNavItem(val route: String, val icon: ImageVector, val label: String) {
Home("homeScreen", Icons.Default.Home, "Home"),
Create("geoMarkerScreen", Icons.Default.Add, "Create"),
Search("mapsScreen", Icons.Default.Search, "Search"),
Settings("settingsScreen", Icons.Default.Settings, "Settings");
}
You can only navigate to a destination that you defined in your
NavHostwith thecomposablebuilder function. You define aScreens.GeoMarkerScreenroute, so if you want to navigate to that screen,item.routeinnavController.navigate(item.route)must be exactly equal to whateverScreens.GeoMarkerScreencontains.Since your question does not tell us what an
itemis or what itsrouteproperty contains, I can only deduce from the exception that is thrown that it does not contain a valid navigation route. You can easly verify that by setting a breakpoint at that line and compare the actual content ofitem.routewithScreens.GeoMarkerScreen.