Home > database >  Navigation drawer below TopAppBar in Jetpack Compose
Navigation drawer below TopAppBar in Jetpack Compose

Time:07-02

  • I am using Jetpack Compose for developing one app which contains multiple screens and we can navigate to them using Navigation Drawer.
  • How can I put my navigation drawer below TopAppBar ( or Toolbar). Below is the gif for the issue:

List item

Below is the composable function for my screen:

fun Home(navController: NavHostController) {
    
        val scaffoldState = rememberScaffoldState()
        val coroutineScope = rememberCoroutineScope()
    
        Scaffold(
            topBar = {
                TopAppBar(
                    title = {
                        Text(
                            buildAnnotatedString {
                                append("Hello World")
                                pushStyle(SpanStyle(fontWeight = FontWeight.Medium, fontSize = 12.sp))
                                append("\[email protected]")
                                pushStyle(SpanStyle(fontWeight = FontWeight.Light, fontSize = 10.sp))
                            }
                        )
                    },
                    navigationIcon = {
                        IconButton(onClick = {
                            coroutineScope.launch {
                                scaffoldState.drawerState.open()
                            }
                        }) {
                            Icon(
                                imageVector = Icons.Outlined.Menu,
                                contentDescription = null
                            )
                        }
                    }
                )
            },
            drawerContent = {},
            scaffoldState = scaffoldState,
            drawerContentColor = MaterialTheme.colors.onBackground,
            content = {
                HomeScreenContent(scaffoldState, navController)
            },
            floatingActionButton = {
                ExtendedFloatingActionButton(
                    text = { Text(text = "Compose") },
                    onClick = { navController.navigate("CreateMsg") },
                    modifier = Modifier.padding(0.dp),
                    icon = {
                        Icon(
                            imageVector = Icons.Outlined.Create,
                            contentDescription = null,
                            tint = Color.White,
                        )
                    },
                    shape = CircleShape,
                    backgroundColor = MaterialTheme.colors.primary
                )
            }
        )
    }

CodePudding user response:

If you want it under your TopAppbar put TopAppbar and Scaffold inside a column as

Column(modifier=Modifier.fillMaxSize()){
  TopAppbar()
  Scaffold()
}

If you want your NavigationDrawer below TopAppbar put them inside a Box with

Box(modifier=Modifier.fillMaxSize()){
  Scaffold()
  TopAppbar()

}

And give your HomeContent topPadding as big as your TopAAppbar's height.

First one

@Composable
private fun MyComposable() {
    val scaffoldState = rememberScaffoldState()

    Column(modifier = Modifier.fillMaxSize()) {

        val coroutineScope = rememberCoroutineScope()

        TopAppBar(
            modifier = Modifier.fillMaxWidth(),
            title = {
                Text(
                    buildAnnotatedString {
                        append("Hello World")
                        pushStyle(SpanStyle(fontWeight = FontWeight.Medium, fontSize = 12.sp))
                        append("\[email protected]")
                        pushStyle(SpanStyle(fontWeight = FontWeight.Light, fontSize = 10.sp))
                    }
                )
            },
            navigationIcon = {
                IconButton(onClick = {
                    coroutineScope.launch {
                        scaffoldState.drawerState.open()
                    }
                }) {
                    Icon(
                        imageVector = Icons.Outlined.Menu,
                        contentDescription = null
                    )
                }
            }
        )

        Scaffold(
            modifier = Modifier
                .fillMaxSize(),
            drawerContent = {},
            scaffoldState = scaffoldState,
            drawerContentColor = MaterialTheme.colors.onBackground,
            content = {
                HomeScreenContent(scaffoldState)
            },
            floatingActionButton = {
                ExtendedFloatingActionButton(
                    text = { Text(text = "Compose") },
                    onClick = { },
                    modifier = Modifier.padding(0.dp),
                    icon = {
                        Icon(
                            imageVector = Icons.Outlined.Create,
                            contentDescription = null,
                            tint = Color.White,
                        )
                    },
                    shape = CircleShape,
                    backgroundColor = MaterialTheme.colors.primary
                )
            }
        )
    }
}

@Composable
fun HomeScreenContent(scaffoldState: ScaffoldState) {
    Column(
        modifier = Modifier
            .fillMaxSize()
            .background(Color.Red)
    ) {

        Text("HOME CONTENT", fontSize = 30.sp, color = Color.White)
    }
}

Second one

@Composable
private fun MyComposable() {
    val scaffoldState = rememberScaffoldState()

    Box(modifier = Modifier.fillMaxSize()) {

        val coroutineScope = rememberCoroutineScope()
        Scaffold(
            modifier = Modifier
                .fillMaxSize(),
            drawerContent = {},
            scaffoldState = scaffoldState,
            drawerContentColor = MaterialTheme.colors.onBackground,
            content = {
                HomeScreenContent(scaffoldState, 56.dp)
            },
            floatingActionButton = {
                ExtendedFloatingActionButton(
                    text = { Text(text = "Compose") },
                    onClick = { },
                    modifier = Modifier.padding(0.dp),
                    icon = {
                        Icon(
                            imageVector = Icons.Outlined.Create,
                            contentDescription = null,
                            tint = Color.White,
                        )
                    },
                    shape = CircleShape,
                    backgroundColor = MaterialTheme.colors.primary
                )
            }
        )

        TopAppBar(
            modifier = Modifier.fillMaxWidth(),
            title = {
                Text(
                    buildAnnotatedString {
                        append("Hello World")
                        pushStyle(SpanStyle(fontWeight = FontWeight.Medium, fontSize = 12.sp))
                        append("\[email protected]")
                        pushStyle(SpanStyle(fontWeight = FontWeight.Light, fontSize = 10.sp))
                    }
                )
            },
            navigationIcon = {
                IconButton(onClick = {
                    coroutineScope.launch {
                        scaffoldState.drawerState.open()
                    }
                }) {
                    Icon(
                        imageVector = Icons.Outlined.Menu,
                        contentDescription = null
                    )
                }
            }
        )

    }
}

@Composable
fun HomeScreenContent(scaffoldState: ScaffoldState, topPadding:Dp) {
    Column(
        modifier = Modifier
            .padding(top= topPadding)
            .fillMaxSize()
            .background(Color.Red)
    ) {

        Text("HOME CONTENT", fontSize = 30.sp, color = Color.White)
    }
}

56.dp is default size for TopAppBar on my device. If you have custom height you need to get it via Modifier.onSizeChanged{} Modifier that set to TopAppBar.

  • Related