简体   繁体   中英

Creating a TopAppBar for each composable with navigation

I am currently using a navigation drawer in jetpack compose, but I have encountered a problem. When I added the navigation drawer to the mainDrawerScreen, it was displaying for every screen I added, in my case it said "Main Menu" for every screen composable when navigated to. This is not ideal.

I decided to remove TopAppBar from mainDrawerScreen and create a seperat scaffold with the TopAppBar for each composable screen. However, now the navigation does not work. I tried to create a trailing lambda for navigation but might have done it the wrong way. Anyone got a suggestion to why it is not opening the navDrawer? Appreciate the feedback!

MainDrawerSCreen:

@SuppressLint("UnusedMaterialScaffoldPaddingParameter")
@Composable
fun MainDrawerScreen() {

   val scaffoldState = rememberScaffoldState(rememberDrawerState(DrawerValue.Closed))
   val scope = rememberCoroutineScope()
   val navController = rememberNavController()


   Scaffold(
       scaffoldState = scaffoldState,
       drawerContent = {

           DrawerHeader()
           DrawerLayout(scope = scope, scaffoldState = scaffoldState , navController = navController)

       }
   ) {
      
       Navigation(navController = navController) // TODO This controls the navigation between different screens
   }
}

My seperate created TopAppBar:

@Composable
fun TopAppBar1(
   scope: CoroutineScope,
   scaffoldState: ScaffoldState,
   text: String,
   onIconClick: () -> Unit
   ) {
   TopAppBar(

       title = { Text(text = text, fontSize = 18.sp) },
       navigationIcon = {
           IconButton(onClick = {
               scope.launch {
                   withContext(Dispatchers.IO) { // should I keep this coroutine on background thread ?
                       scaffoldState.drawerState.open()
                   }
               }
           }) {
               Icon(
                   Icons.Filled.Menu, "Menu",
                   Modifier.clickable { onIconClick.invoke()})
           }
       },
       backgroundColor = LightBlue,
       contentColor = MaterialTheme.colors.onPrimary,

       )
}

ProfileScreen:

@SuppressLint("UnusedMaterialScaffoldPaddingParameter")
@Composable
fun ProfileScreen1() {

   val scaffoldState = rememberScaffoldState(rememberDrawerState(DrawerValue.Closed))
   val scope = rememberCoroutineScope()


   Scaffold(
   topBar = {
       TopAppBar1(scope = scope, scaffoldState = scaffoldState, text = "Profile") {
           scope.launch { scaffoldState.drawerState.currentValue }     <----------- Trailing Lambda
       }
},
   content = {
       ActualBackground() // Background

       Column(
           modifier = Modifier
               .fillMaxSize(),
           verticalArrangement = Arrangement.Center,
           horizontalAlignment = Alignment.CenterHorizontally,
       ) { // Content }

         

I show you what I did:

TopAppBar.kt:

@Composable
fun TopAppBarScreen(
    title: String = "",
    screen: String,
    navController: NavController
) {
    TopAppBar(
        title = {
            Text(
                text = title,
                style = Typography.h2
            )
        },
        navigationIcon = {
            IconButton(
                onClick = {
                    navController.navigate(screen)
                }
            ) {
                Icon(Icons.Filled.ArrowBack, "backIcon")
            }
        },
        backgroundColor = Color.Background,
        contentColor = Color.BackgroundDarkGrey,
        elevation = 0.dp,
    )
}

Navigation.kt

@Composable
fun Navigation() {
    val navController = rememberNavController()
    val viewModel = hiltViewModel<CountrySelectorViewModel>()
    val userViewModel = InputViewModel(LocalContext.current)
    NavHost(
        navController = navController,
        startDestination = Screen.WELCOME_SCREEN
    ) {
        composable(Screen.WELCOME_SCREEN) {
            WelcomeScreen(navController = navController)
        }
}

Screen:

object Screen {
    const val WELCOME_SCREEN = "WelcomeScreen"
}

When I call my TopAppBar:

TopAppBarScreen(
        screen = Screen.WELCOME_SCREEN,
        navController = navController
)

Look at how the navigation works and it's the same if you are using a button to change screen.

I hope this can help you

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM