A highly customizable Curved Bottom Navigation bar for Jetpack Compose, built with Kotlin Multiplatform to support both Android and iOS.
2025-10-27.01-45-04.mov
When Edge to Edge enabled - Full Navigation Example
- Set The surface to cover the transparent navigation bar (systemBar) with the navigation bar color
setContent {
Surface(
color = Color(0xffEEE9FF)
) {
App()
}
}
- give it a navigationBarsPadding, so that it doesn't interfere with the system bars
CurvedBottomNavigation(
modifier = Modifier.align(Alignment.BottomCenter).navigationBarsPadding(),
- Highly Customizable: Almost every aspect of the navigation bar can be customized, from colors and sizes to animation styles.
- Kotlin Multiplatform: A single codebase for both Android and iOS.
- Built with Compose: Leverages the power and flexibility of Jetpack Compose.
- Three Curve Animation Styles: Choose from
SMOOTH,DYNAMIC, orBOUNCYanimations. - Easy to Use: Simple integration with just a few lines of code.
This project is not yet available as a library. This feature is coming soon!
In the meantime, you can use it by following these steps:
- Fork this repository.
- Copy the
animatedBottomBarpackage (composeApp/src/commonMain/kotlin/io/jadu/animatedBottomBar) into your own project's multiplatform module. - That's it! You can now use the
CurvedBottomNavigationcomposable and start customizing it.
First, define your navigation items. Each NavItem now requires icons wrapped in IconSource.
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.*
import androidx.compose.material.icons.outlined.*
import io.jadu.animatedBottomBar.models.IconSource
import io.jadu.animatedBottomBar.models.NavItem
val navItems = listOf(
NavItem(
icon = IconSource.Vector(Icons.Outlined.Home),
selectedIcon = IconSource.Vector(Icons.Filled.Home),
label = "Home",
route = "home"
),
NavItem(
icon = IconSource.Vector(Icons.Outlined.Search),
selectedIcon = IconSource.Vector(Icons.Filled.Search),
label = "Search",
route = "search"
),
NavItem(
icon = IconSource.Drawable(R.drawable.ic_custom),
selectedIcon = IconSource.Drawable(R.drawable.ic_custom_filled),
label = "Custom",
route = "custom"
),
// ... more items
)NavItem now supports two types of icon sources:
IconSource.Vector: Use Material Icons or customImageVectorIconSource.Drawable: Use drawable resources from your project
Then, add the CurvedBottomNavigation composable to your UI. It works well within a Scaffold:
var selectedIndex by remember { mutableStateOf(0) }
Scaffold(
bottomBar = {
CurvedBottomNavigation(
items = navItems,
selectedIndex = selectedIndex,
onItemSelected = { index ->
selectedIndex = index
}
)
}
) {
// Your main screen content, which can change based on selectedIndex
SampleScreens(currentIndex = selectedIndex)
}For more complex apps with navigation, you can integrate with Jetpack Navigation Compose:
You can customize almost every part of the navigation bar. Here are the available options:
| Parameter | Type | Description |
|---|---|---|
items |
List<NavItem> |
The list of navigation items to display. |
selectedIndex |
Int |
The index of the currently selected item. |
modifier |
Modifier |
A Modifier for the component. |
bottomBarAlignment |
Alignment |
Alignment of the bottom bar in its parent. |
curveAnimationType |
CurveAnimationType |
Animation style for the curve (SMOOTH, DYNAMIC, BOUNCY). |
animationDuration |
Int |
Duration for the animations in milliseconds. |
fabBackgroundColor |
Color |
Background color of the floating action button (FAB). |
fabIconTint |
Color |
Tint color for the selected icon on the FAB. |
fabDotColor |
Color |
Color of the indicator dot below the FAB icon. |
navBarBackgroundColor |
Color |
Background color of the navigation bar itself. |
unselectedIconTint |
Color |
Tint color for the unselected icons. |
unselectedTextColor |
Color |
Color for the unselected item labels. |
fabSize |
Dp |
The size (diameter) of the FAB. |
fabIconSize |
Dp |
The size of the icon inside the FAB. |
fabDotSize |
Dp |
The size of the dot indicator. |
enableFabIconScale |
Boolean |
If true, the FAB icon will have a scaling animation. |
navBarHeight |
Dp |
The height of the navigation bar. |
unselectedIconSize |
Dp |
The size of the unselected icons. |
unselectedTextSize |
TextUnit |
Font size for the unselected item labels. |
fabElevation |
Dp |
Elevation (shadow) of the FAB. |
curveRadius |
Dp |
The radius of the curve on the top edge. |
curveDepth |
Dp |
How deep the curve cuts into the bar. |
curveSmoothness |
Dp |
Controls the smoothness of the curve's edges. |
showDot |
Boolean |
Whether to show the small dot indicator. |
showLabels |
Boolean |
Whether to show text labels for unselected items. |
enableHapticFeedback |
Boolean |
If true, the device will vibrate on item selection. |
onItemSelected |
(Int) -> Unit |
A callback that is invoked when an item is selected. |
SMOOTH: A simple, elegant animation usingFastOutSlowInEasing.DYNAMIC: A more playful animation using a medium-bouncy spring.BOUNCY: A very energetic animation with a high-bouncy spring.
Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement".
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature) - Commit your Changes (
git commit -m 'Add some AmazingFeature') - Push to the Branch (
git push origin feature/AmazingFeature) - Open a Pull Request
Have an idea for a new feature? Open an issue to discuss it. We're always looking to improve the library.
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Built with love ❤️ by Jadu