30

We can have Navigation Drawer in JetpackCompose by using Scaffold as below

Scaffold(
    drawerContent = { Text(text ="Drawer") }
) {}

enter image description here

I want to make the width of the drawer smaller. How can I do so?

2

5 Answers 5

12

You can modify the shape (including width and height) using drawerShape parameter in Scaffold method.

So for instance

 Scaffold(
    scaffoldState = scaffoldState,
    drawerContent = { Text("Drawer content") },
    drawerShape = customShape(),
    content = {inner padding -> /* Body*/}
)

Then your customShape function

fun customShape() =  object : Shape {
    override fun createOutline(
        size: Size,
        layoutDirection: LayoutDirection,
        density: Density
        ): Outline {
            return Outline.Rectangle(Rect(0f,0f,100f /* width */, 131f /* height */))
     }
 }

You can also use Outline.Rounded to get rounded corners

Sign up to request clarification or add additional context in comments.

10 Comments

May be the best solution at the moment until a property for modifying drawer width is hopefully added to Scaffold. My only worry is if creating a Shape inside Composable functions could lead to slowdowns. I've tested that the above code works, but haven't profiled it yet in a real app.
@kabumere I don't think it would slow down the app since internally, various composable functions use Material shapes (including the default drawerShape here; I'll check my pc and get the actual shape) which are actually functions similar to what I provided. Nonetheless, you can always make customShape a val and not a fun so the Shape object would be created once
Yeah, mine was a val inside of a Composable function. I just started using Compose, so I guess I'm still wrapping my head around what gets re-called during recomposition and what doesn't.
This work if you want the drawer to be smaller. but if you want it to be larger (ex: full screen width). The drawer looks like it is larger but the content is still limited. All is truncaded. Any one have any idea on how to solves that ?
@kc_dev return Outline.Rectangle(Rect(0f,0f,100f /* width */, size /* height */))
|
2

Here is an example drawing a Scaffold custom shape.

1. Spec exact size.

Scaffold(
    drawerShape = NavShape(400.dp, 0f)
)

2. Spec size by percent (half screen).

Scaffold(
    drawerShape = NavShape(0.dp, 0.5f)
)

Custom shape class

class NavShape(
    private val widthOffset: Dp,
    private val scale: Float
) : Shape {

    override fun createOutline(
        size: Size,
        layoutDirection: LayoutDirection,
        density: Density
    ): Outline {
        return Outline.Rectangle(
            Rect(
                Offset.Zero,
                Offset(
                    size.width * scale + with(density) { widthOffset.toPx() },
                    size.height
                )
            )
        )
    }
}

Comments

0

I accomplished that by:

#1 - Setting to the Drawer's content Modifier a max width:

@Composable
fun MyDrawerContent(){
     Column(Modifier.fillMaxHeight().width(300.dp)) {
          ...
        

#2 - Setting the Scafold's drawer colors to Transparent + no Elevation

Scaffold(
     drawerBackgroundColor = Color.Transparent,
     drawerContentColor = Color.Transparent,
     drawerElevation = 0.dp,
     drawerContent = {
          MyDrawerContent()
     },
     ...

Note: Only problem I faced is if you touch on the transparent area the drawer does not closes as it used to. Siding it to close works perfectly though. It's a workaround...

Comments

-4

Have you tried adding a modifier inside your drawer composable ?

Something like this:

Scaffold(drawerContent = { 
        Box(modifier = Modifier.fillMaxWidth(0.9f){
            Text(text = "Drawer") 
        }
    }) {}

3 Comments

It doesn't work :(. This just set the content width within the drawer. The drawer width is still the same.
@Elye ah right, maybe don't use Scaffold but ModalDrawerLayout directly, that way you can use its modifier
@ CyrilFind, It won't work with Modal drawer. Modal drawer represents the entire screen along with nav menu, not just the nav menu.
-4
Scaffold(
      topBar = {
          topBar()
      },
      scaffoldState = scaffoldState,
      drawerContent = {
          drawer()
      },
      drawerGesturesEnabled = true
  ) { innerPadding ->
      NavigationHost(navController = navController)
  }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.