When implementing a rounded bottom navigation bar in Jetpack Compose, you might encounter an issue where the system padding becomes visible in the corners, disrupting the clean, rounded appearance you're aiming for. Let's break down the root cause and how to resolve this common UI problem.
The Cause
In the image below, you can see unwanted edges in the corners that aren't clipped by the navigation bar. These edges are caused by the scaffold padding (innerPadding
), which is used to manage the padding for the bottom bar, top bar, and system bars, ensuring UI elements don't overlap. While this padding is useful for layout adjustments, it interferes with achieving a seamless, rounded design for the bottom navigation bar.
Cases and Solutions
1. Using a LazyColumn
Inside Another Container:
-
Cause:
The issue often arises when using a
LazyColumn
inside another container, such as aColumn
, where the height of theLazyColumn
is constrained by the parent container defined in theScaffold
. Consider the following example:
Scaffold(
containerColor = Color(0xFFC9E4FD),
topBar = { AppBar() },
bottomBar = { BottomBar() }
) { innerPadding ->
Column(
verticalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier.padding(innerPadding)
) {
Box(
modifier = Modifier
.padding(8.dp)
.background(
Color.DarkGray,
shape = RoundedCornerShape(16.dp)
)
.width(200.dp)
.height(100.dp)
) {
Greeting("Android")
}
LazyColumn(
contentPadding = PaddingValues(8.dp),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
items(10) {
Box(
modifier = Modifier
.background(
Color(0xFF001E30),
shape = RoundedCornerShape(16.dp)
)
.fillMaxWidth()
.height(100.dp)
) {
Greeting("Android")
}
}
}
}
}
-
Solution:
To remove the extra padding, adjust the
innerPadding
values:
val topPadding = innerPadding.calculateTopPadding()
var bottomPadding = innerPadding.calculateBottomPadding()
if (bottomPadding > 0.dp) bottomPadding -= 15.dp
Column(
modifier = Modifier.padding(top = topPadding, bottom = bottomPadding)
) {
// Your UI components here
}
This solution reassigns the value of the bottom padding to remove the extra padding. The if
condition ensures the padding value remains non-negative, preventing errors like this:
FATAL EXCEPTION: main
Process: com.example.bottombar, PID: 25016
java.lang.IllegalArgumentException: Padding must be non-negative
- Complete Code for the First Solution:
Scaffold(
containerColor = Color(0xFFC9E4FD),
topBar = { AppBar() },
bottomBar = { BottomBar() }
) { innerPadding ->
val topPadding = innerPadding.calculateTopPadding()
var bottomPadding = innerPadding.calculateBottomPadding()
if (bottomPadding > 0.dp) bottomPadding -= 10.dp
Column(
modifier = Modifier.padding(
top = topPadding,
bottom = bottomPadding
)
) {
Box(
modifier = Modifier
.padding(8.dp)
.background(
Color.DarkGray,
shape = RoundedCornerShape(16.dp)
)
.width(200.dp)
.height(100.dp)
) {
Greeting("Android")
}
LazyColumn(
contentPadding = PaddingValues(
top = 8.dp,
bottom = 20.dp,
start = 8.dp,
end = 8.dp
),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
items(10) {
Box(
modifier = Modifier
.background(
Color(0xFF001E30),
shape = RoundedCornerShape(16.dp)
)
.fillMaxWidth()
.height(100.dp)
) {
Greeting("Android")
}
}
}
}
}
2. Assigning innerPadding
to LazyColumn
:
-
Cause:
If you assign the
innerPadding
directly to theLazyColumn
usingModifier.padding()
, it can cause the same issue. Here's an example:
Scaffold(
containerColor = Color(0xFFC9E4FD),
topBar = { AppBar() },
bottomBar = { BottomBar() }
) { innerPadding ->
LazyColumn(
verticalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier.padding(innerPadding)
) {
items(10) {
Box(
modifier = Modifier
.background(
Color(0xFF001E30),
shape = RoundedCornerShape(16.dp)
)
.fillMaxWidth()
.height(100.dp)
) {
Greeting("Android")
}
}
}
}
-
Solution:
Instead of applying
innerPadding
directly to theLazyColumn
's modifier, assign it to thecontentPadding
parameter:
Scaffold(
containerColor = Color(0xFFC9E4FD),
topBar = { AppBar() },
bottomBar = { BottomBar() }
) { innerPadding ->
LazyColumn(
contentPadding = innerPadding,
verticalArrangement = Arrangement.spacedBy(8.dp),
modifier = Modifier.padding(8.dp)
) {
items(10) {
Box(
modifier = Modifier
.background(
Color(0xFF001E30),
shape = RoundedCornerShape(16.dp)
)
.fillMaxWidth()
.height(100.dp)
) {
Greeting("Android")
}
}
}
}
By assigning innerPadding
to contentPadding
, this fixes the problem and ensures that the padding is handled correctly without affecting the rounded corners of your bottom navigation bar.
Final Result
Conclusion
These two solutions address the common issue of visible system padding interfering with the rounded corners of a bottom navigation bar in Jetpack Compose. By either adjusting the padding for the whole layout or assigning innerPadding
to contentPadding
, you can achieve a clean, rounded appearance without the unwanted white edges.
Follow me:
If you found this post helpful, please follow me on GitHub and LinkedIn!
Share your thoughts:
I’d love to hear your opinion or any alternative solutions you think might work better. Let’s discuss in the comments!
Top comments (0)