Organize navigation root for Kotlin Multiplatform project

  Kiến thức lập trình

i’m struggling to organize my RootNavigation.kt in my kotlin multiplatform project. I want to navigate between auth screens, then some screens with information about the app and finally the user can enter the app and navigate using a bottom bar. the bottom bar just appears once the user passed the auth and information screens.

I tried to use different AppGraphs to organize the routes of my app but when to navigate between the last information screen to the home page the app crashes.

package com.itlab.match_academico.util

import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Email
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.Person
import androidx.compose.material.icons.outlined.Email
import androidx.compose.material.icons.outlined.Home
import androidx.compose.material.icons.outlined.Person
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.navigation
import com.itlab.match_academico.features.opening.information.InformationScreenRoot
import com.itlab.match_academico.features.opening.mision.MisionScreenRoot
import com.itlab.match_academico.features.opening.welcome.WelcomeScreenRoot
import com.itlab.match_academico.features.quiz.presentation.DragAndDropBoxes
import features.auth.presentation.intro.IntroScreenRoot
import features.auth.presentation.login.LoginScreenRoot
import features.home.presentation.HomeScreen
import features.home.presentation.HomeScreenRoot
import features.profile.presentation.ProfileScreen
import features.profile.presentation.ProfileScreenRoot
import features.resources.presentation.ResourcesScreen
import features.resources.presentation.ResourcesScreenRoot
import ui.components.BottomNavigationBarContent
import ui.components.OnlyLogoTopBar

sealed class RootScreen(
    val route: String,
    val selectedIcon: ImageVector?,
    val unselectedIcon: ImageVector?,
    val title: String
) {
    data object Home : RootScreen("home", Icons.Filled.Home, Icons.Outlined.Home, "Home")
    data object Resources :
        RootScreen("recursos", Icons.Filled.Email, Icons.Outlined.Email, "Recursos")

    data object Profile :
        RootScreen("profile", Icons.Filled.Person, Icons.Outlined.Person, "Profile")
}

@Composable
fun RootNavigation(
    mainNavHostController: NavHostController,
    openingNavHostController: NavHostController,
    appNavHostController: NavHostController
) {
    NavHost(
        mainNavHostController,
        startDestination = "intro"
    ) {
        mainAppGraph(appNavHostController)
        openingGraph(openingNavHostController)
        authGraph(mainNavHostController)
    }
}

private fun NavGraphBuilder.authGraph(navController: NavHostController) {
    composable(route = "intro") {
        IntroScreenRoot(
            onSingUpClick = {
                navController.navigate("register")
            }, //No tenemos register
            onSingInClick = {
                navController.navigate("login")
            }
        )
    }
    composable("login") {
        LoginScreenRoot(
            onLoginClick = {
                navController.navigate("opening") {
                    popUpTo("login") { inclusive = true }
                }
            }
        )
    }
}

private fun NavGraphBuilder.openingGraph(navController: NavHostController) {
    composable(route = "opening") {
        OpeningScreen(navController)
    }
}

@Composable
fun OpeningScreen(navController: NavHostController) {
    Scaffold(
        topBar = {
            OnlyLogoTopBar()
        }
    ) { innerPadding ->
        NavHost(
            navController = navController,
            startDestination = "dragndrop",
            modifier = Modifier.padding(innerPadding)
        ) {
            composable("dragndrop"){
                DragAndDropBoxes()
            }
            composable("welcome") {
                WelcomeScreenRoot(
                    Modifier,
                    onNextClick = {
                        navController.navigate("info")
                    }
                )
            }
            composable("info") {
                InformationScreenRoot(
                    Modifier,
                    onNextClick = {
                        navController.navigate("mision")
                    }
                )
            }
            composable("mision") {
                MisionScreenRoot(
                    Modifier,
                    onNextClick = {
                        navController.navigate("mainApp") {
                            popUpTo("mision") { inclusive = true }
                        }
                    }
                )
            }
        }
    }
}

private fun NavGraphBuilder.mainAppGraph(navController: NavHostController) {
    composable(route = "mainApp") {
        MainAppScreen(navController)
    }
}

@Composable
fun MainAppScreen(navController: NavHostController) {
    Scaffold(
        topBar = {
            OnlyLogoTopBar()
        },
        bottomBar = {
            BottomNavigationBarContent(navController = navController)
        }
    ) { innerPadding ->
        NavHost(
            navController = navController,
            startDestination = RootScreen.Home.route,
            modifier = Modifier.padding(innerPadding)
        ) {
            composable(RootScreen.Home.route) {
                HomeScreenRoot(Modifier)
            }
            composable(RootScreen.Resources.route) {
                ResourcesScreenRoot(Modifier)
            }
            composable(RootScreen.Profile.route) {
                ProfileScreenRoot(Modifier)
            }
        }
    }
}

This is the code i’m using at the moment. I’m not sure if i should continue using navigation compose or if it would be easier to use a library for the navigation feature.

New contributor

Hideki Sotero is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

Theme wordpress giá rẻ Theme wordpress giá rẻ Thiết kế website

LEAVE A COMMENT