|
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"), |
|
) |
|
) |
|
}, |
|
) { ... } |
|
} |