How to change the color of the cut out for the bottom bar?
I know it takes the color from MaterialTheme.colors.background, but I don't want to change the background color for all components, only for the bottom bar. (The white color in the cut out in the picture.)
I have tried different things, for example setting a new theme just for the bottom bar, but that doesn't work.
val bottomBarColors = MaterialTheme.colors.copy(background = Color.LightGray)
...
bottomBar = {
MaterialTheme(
colors = bottomBarColors,
typography = MaterialTheme.typography,
shapes = MaterialTheme.shapes
) {
BottomAppBar(
cutoutShape = fabShape,
content = {
MyBottomNavigation(navController, bottomNavigationItems)
})
}
}
In your case you can apply the Modifier.background to the BottomAppBar:
bottomBar = {
BottomAppBar(
modifier = Modifier.background(Color.Red),
cutoutShape = fabShape) {
BottomNavigation {
/* .... */
}
}
}
The solution was easier than I thought. Just add something below the bottom bar:
bottomBar = {
Box {
Spacer(modifier = Modifier.matchParentSize().background(color = Color.Blue))
BottomAppBar(
cutoutShape = fabShape,
content = {
MyBottomNavigation(navController, bottomNavigationItems)
})
}
}
Related
Now the icon always in the start, what should I do to align the icon to the end? I tried to use modifier but doesn't work. Thank you in advance.
If you want an Icon aligned at the end in the TopAppBar use the actions parameter instead of the navigationIcon.
Something like:
TopAppBar(
title = { Text("Simple TopAppBar") },
backgroundColor = Red,
actions = {
// RowScope here, so these icons will be placed horizontally
IconButton(onClick = { /* doSomething() */ }) {
Icon(Icons.Filled.Close, contentDescription = null)
}
}
)
I want to create animated bottomAppBar in jetpack compose (something like image) but Fab position in jetpack compose is only center or end and i need to move FAB to left at least, my code is :
#Composable
fun BottomBarSample() {
Scaffold(
floatingActionButton = {
FloatingActionButton(
shape = CircleShape,
onClick = {},
) {
Icon(imageVector = Icons.Filled.Add, contentDescription = "icon")
}
},
floatingActionButtonPosition = FabPosition.End,
isFloatingActionButtonDocked = true,
bottomBar = {
BottomAppBar(backgroundColor = Color.Cyan, cutoutShape = CircleShape) {
}
}
){
//body
}
}
I guess this is not a good approach as we are changing the layout direction, but you can modify the layout direction from LTR to RTL using CompositionLocalProvider
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl ) {
BottomBarSample()
}
Since there is no FabPosition.Start yet using LocalLayoutDirection is easiest way to create cutout at the beginning. Other option is to create your layout using path operations or blending modes.
In this example i show how to cut out using BlendModes but if you want elevation you need to use Path by creating shape as it's done in source code
After changing layout direction to right to left you should change direction inside content, bottomBar or other lambdas you use
#Composable
fun BottomBarSample() {
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {
Scaffold(
floatingActionButton = {
FloatingActionButton(
shape = CircleShape,
onClick = {},
) {
Icon(imageVector = Icons.Filled.Add, contentDescription = "icon")
}
},
floatingActionButtonPosition = FabPosition.End,
isFloatingActionButtonDocked = true,
bottomBar = {
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Ltr) {
BottomAppBar(backgroundColor = Color.Cyan, cutoutShape = CircleShape) {
}
}
}
) {
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Ltr) {
//body
}
}
}
}
I'm using the new Material 3 NavigationBar and NavigationBarItem components, I want the NavigationBar to be thinner, because the default one is too large. I want one similar to the one Gmail or Drive has (see picture at the end for the comparison). Making the icon smaller doesn't work, and neither changing all the available paddings (Icon, NavigationBar and NavigationBarItem).
This is the Composable code, if I change the NavigationBar heigh (using Modifier) then this happens:
I primarly want to remove the space between the label and the bottom, and the one between the top and the icon.
#Composable
fun MyAppBottomBar(navController: NavController, tabs: Array<MenuBottom>) {
val navBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = navBackStackEntry?.destination?.route ?: MenuBottom.INICIO.route
val rutas = remember { MenuBottom.values().map { it.route } }
if (currentRoute in rutas) {
NavigationBar(containerColor = elevation01) {
tabs.forEachIndexed { index, item ->
NavigationBarItem(
selected = currentRoute == item.route,
onClick = {
if (item.route != currentRoute) {
navController.navigate(item.route) {
popUpTo(navController.graph.startDestinationId) {
saveState = true
}
launchSingleTop = true
restoreState = true
}
}
},
label = { Text(stringResource(id = item.title)) },
icon = {
if (item.route == currentRoute) {
Icon(item.selectedIcon, contentDescription = null, tint = Color.Black)
} else {
Icon(item.unselectedIcon, contentDescription = null)
}
},
colors = NavigationBarItemDefaults.colors(
selectedIconColor = Color.Black,
unselectedIconColor = Color.Black,
indicatorColor = Greenyellow,
selectedTextColor = Color.Black,
unselectedTextColor = Color.Black
)
)
}
}
}
}
NavigationBar does not use padding. It uses a fixed height. How do I know that? While working with MUI (which is a React implementation of Material design) I found that they use a fixed height, and margin: auto to center items vertically. Then I figured jetpack compose NavigationBar might do the same and the idea was right. So whats the solution?
NavigationBar(
modifier = Modifier.height(64.dp)
) {...}
Or change it to your taste. It will shrink and grow the space taken up.
This most likely has to do with the bottom navigation. The grey bar you see has its own padding by default.
Have a look at this documentation on how to remove those System intents.
Here's what you need to do in a nutshell:
implementation "com.google.accompanist:accompanist-insets:<version>"
Then in your MainActivity call WindowCompat.setDecorFitsSystemWindows(window, false) like this:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(window, false)
setContent {...}
}
Now your App should use the entire Screen and your NavigationBar should have the same height as the one from Gmail.
To apply single ones of them again e.g. StatusBar call a modifier:
Modifier.statusBarsPadding()
Migrating an app in view system to Jetpack compose.
The bottom sheet scrim color is shown on the status bar in the current app.
How to reproduce the same in Jetpack compose?
Screenshot of the app using views
Screenshot of the app using compose
Compose Code
val modalBottomSheetState = rememberModalBottomSheetState(
initialValue = ModalBottomSheetValue.Hidden,
)
val coroutineScope = rememberCoroutineScope()
ModalBottomSheetLayout(
sheetState = modalBottomSheetState,
sheetContent = {
// Not relevant
},
) {
Scaffold(
scaffoldState = scaffoldState,
topBar = {
// Not relevant
},
floatingActionButton = {
FloatingActionButton(
onClick = {
coroutineScope.launch {
if (!modalBottomSheetState.isAnimationRunning) {
if (modalBottomSheetState.isVisible) {
modalBottomSheetState.hide()
} else {
modalBottomSheetState.show()
}
}
}
},
) {
Icon(
imageVector = Icons.Rounded.Add,
contentDescription = "Add",
)
}
},
modifier = Modifier
.fillMaxSize(),
) { innerPadding ->
// Not relevant - Nav graph code
}
}
try to use the System UI Controller in the accompanist library to control the statusBar Color and navigationBar color
implementation "com.google.accompanist:accompanist-systemuicontroller:0.18.0"
// Remember a SystemUiController
val systemUiController = rememberSystemUiController()
val useDarkIcons = MaterialTheme.colors.isLight
SideEffect {
// Update all of the system bar colors to be transparent, and use
// dark icons if we're in light theme
systemUiController.setSystemBarsColor(
color = Color.Transparent,
darkIcons = useDarkIcons
)
// setStatusBarsColor() and setNavigationBarsColor() also exist
}
In the latest versions of Compose, there's a statusBarColor parameter that is set in the Theme.kt file by default. If you're not using accompanist, try altering that value to get the desired effect.
You can remove automatic insects and make status bar transparent:
WindowCompat.setDecorFitsSystemWindows(window, false)
window.statusBarColor = android.graphics.Color.TRANSPARENT;
Then draw your bottom sheet and it will go under all system bars including status bar
Just don't forget to add insects for the rest of the views when needed, it's in compose foundation now:
modifier = Modifier
.navigationBarsPadding()
.captionBarPadding()
.imePadding()
.statusBarsPadding(),
I'd like to use Toolbar with Jetpack Compose. Does it have such a Composable component?
You can use the TopAppBar.
The best way is to use it with the Scaffold. Something like:
Scaffold(
topBar = {
TopAppBar(
title = {
Text(text = "TopAppBar")
},
navigationIcon = {
IconButton(onClick = { }) {
Icon(Icons.Filled.Menu,"")
}
},
backgroundColor = Color.Blue,
contentColor = Color.White,
elevation = 12.dp
)
}, content = {
})
Using
compose_version = '1.0.0-beta01'
TopAppBar(
title = {
Text(text = "Pets Show")
},
navigationIcon = {
IconButton(onClick = { }) {
Icon(imageVector = Icons.Filled.Menu, contentDescription = "Menu Btn")
}
},
backgroundColor = Color.Transparent,
contentColor = Color.Gray,
elevation = 2.dp
)
TopAppBar is a pre-defined composable that will help you accomplish what you want. You can use it with Scaffold in order to get basic material design scaffolding to hook up the TopAppBar.
Here is an example with detailed comments to see how to use it - https://github.com/vinaygaba/Learn-Jetpack-Compose-By-Example/blob/1f843cb2bf18b9988a0dfc611b631f216f02149e/app/src/main/java/com/example/jetpackcompose/material/FixedActionButtonActivity.kt#L70
Copying it here to make it easy to consume
// Scaffold is a pre-defined composable that implements the basic material design visual
// layout structure. It takes in child composables for all the common elements that you see
// in an app using material design - app bar, bottom app bar, floating action button, etc. It
// also takes care of laying out these child composables in the correct positions - eg bottom
// app bar is automatically placed at the bottom of the screen even though I didn't specify
// that explicitly.
Scaffold(
scaffoldState = scaffoldState,
topAppBar = { TopAppBar(title = { Text("Scaffold Examples") }) },
bottomAppBar = { fabConfiguration ->
// We specify the shape of the FAB bu passing a shape composable (fabShape) as a
// parameter to cutoutShape property of the BottomAppBar. It automatically creates a
// cutout in the BottomAppBar based on the shape of the Floating Action Button.
BottomAppBar(fabConfiguration = fabConfiguration, cutoutShape = fabShape) {}
},
floatingActionButton = {
FloatingActionButton(
onClick = {},
// We specify the same shape that we passed as the cutoutShape above.
shape = fabShape,
// We use the secondary color from the current theme. It uses the defaults when
// you don't specify a theme (this example doesn't specify a theme either hence
// it will just use defaults. Look at DarkModeActivity if you want to see an
// example of using themes.
backgroundColor = MaterialTheme.colors.secondary
) {
IconButton(onClick = {}) {
Icon(asset = Icons.Filled.Favorite)
}
}
},
floatingActionButtonPosition = Scaffold.FabPosition.CenterDocked,
bodyContent = { modifier ->
// Vertical scroller is a composable that adds the ability to scroll through the
// child views
VerticalScroller {
// Column is a composable that places its children in a vertical sequence. You
// can think of it similar to a LinearLayout with the vertical orientation.
Column(modifier) {
repeat(100) {
// Card composable is a predefined composable that is meant to represent
// the card surface as specified by the Material Design specification. We
// also configure it to have rounded corners and apply a modifier.
Card(color = colors[it % colors.size],
shape = RoundedCornerShape(8.dp),
modifier = Modifier.padding(8.dp)
) {
Spacer(modifier = Modifier.fillMaxWidth() + Modifier.preferredHeight(200.dp))
}
}
}
}
}
)
Yes, it's TopAppBar (in androidx.ui.material). It allows you to specify a title, color, navigation icon, and actions. See the documentation for more information.