Skip to content

Instantly share code, notes, and snippets.

@pinneer19
Last active September 22, 2024 09:36
Show Gist options
  • Save pinneer19/69a612e3fffa7e93d1e2734d1c3a1548 to your computer and use it in GitHub Desktop.
Save pinneer19/69a612e3fffa7e93d1e2734d1c3a1548 to your computer and use it in GitHub Desktop.
Custom navigation bar with center cutout in Jetpack Compose
data class NavBarItem(val icon: ImageVector, val text: String)
@Composable
fun CustomNavBar(modifier: Modifier = Modifier, navBarItems: List<NavBarItem>) {
val primary = MaterialTheme.colorScheme.primary
val context = LocalContext.current
require(navBarItems.size % 2 == 0)
Row(
horizontalArrangement = Arrangement.SpaceAround,
modifier = modifier
.padding(start = 10.dp, end = 10.dp, bottom = 10.dp)
.shadow(elevation = 10.dp, shape = RoundedCornerShape(30.dp))
.drawBehind {
val navBarHeight = 64.dp.toPx()
val cutoutWidth = 72.dp.toPx()
val cutoutHeight = 64.dp.toPx()
val cornerRadius = 36.dp.toPx()
val left = center.x - cutoutWidth / 2
val top = -cutoutHeight / 2
val right = center.x + cutoutWidth / 2
val bottom = top + cutoutHeight
val path = Path().apply {
moveTo(0f, 0f)
lineTo(left - cornerRadius, 0f)
cubicTo(
left, 0f,
left, 0f,
left, cornerRadius
)
lineTo(left, bottom - cornerRadius)
cubicTo(
left, bottom,
left, bottom,
left + cornerRadius, bottom
)
lineTo(right - cornerRadius, bottom)
cubicTo(
right, bottom,
right, bottom,
right, bottom - cornerRadius
)
lineTo(right, cornerRadius)
cubicTo(
right, 0f,
right, 0f,
right + cornerRadius, 0f
)
lineTo(size.width, 0f)
lineTo(size.width, navBarHeight)
lineTo(0f, navBarHeight)
close()
}
drawPath(path = path, color = primary, style = Fill)
}
) {
navBarItems.forEach {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.clickable {
Toast
.makeText(context, "Click on: ${it.text}", Toast.LENGTH_SHORT)
.show()
}
.padding(5.dp)
) {
Icon(
imageVector = it.icon,
tint = MaterialTheme.colorScheme.onPrimary,
contentDescription = null,
)
Text(text = it.text, color = MaterialTheme.colorScheme.onPrimary)
}
}
}
}
// Usage example with FAB as center button
@Composable
fun CutoutNavBarScaffold() {
Scaffold(
modifier = Modifier.fillMaxSize(),
floatingActionButton = {
FloatingActionButton(
modifier = Modifier.offset(y = 40.dp),
onClick = {
Toast.makeText(this, "Hi from fab", Toast.LENGTH_SHORT).show()
}) {
Icon(
imageVector = Icons.Default.ThumbUp,
contentDescription = null,
tint = Color.Blue
)
}
},
floatingActionButtonPosition = FabPosition.Center,
bottomBar = {
CustomNavBar(
modifier = Modifier
.fillMaxWidth()
.navigationBarsPadding(),
navBarItems = listOf(
NavBarItem(Icons.Default.Home, "Home"),
NavBarItem(Icons.Default.Search, "Search"),
)
)
},
) { ... }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment