How to Align the Icon to the End in TopAppBar jetpack compose - android

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)
}
}
)

Related

Reduce padding in NavigationBar with Material 3

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()

Jetpack compose - change bottom bar cutout color

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)
})
}
}

Android Jetpack Compose white TabRow

I am trying to get Tabs working with a TabRow on Android with compose. What I'd like is the TabRow to have a white background.
The default color seems to be this purple(ish) as shown in the documentation (https://developer.android.com/reference/kotlin/androidx/compose/material/package-summary).
When I set backgroundColor to White the Tabs are grey for some reason.
How would you achieve white Tabs in Compose?
Thanks!
EDIT: Google have now fixed this issue: https://issuetracker.google.com/issues/197254738. Hopefully it will find its way into a JC release soon!
Question's a couple of months old, but recently encountered this issue so others might find these solutions useful:
Solution 0 (quickest)
Don't have a divider. For example:
TabRow(
selectedTabIndex = ...,
modifier = Modifier.height(100.dp).fillMaxWidth(),
divider = {}
) { /* content here */ }
Solution 1
Since the TabRow is just a container, don't specify a height in its modifier. If you want it to have a custom height, instead make sure that each of the Tabs have their heights specified explicitly. For example:
var selectedTabIndex by remember { mutableStateOf(0) }
TabRow(
selectedTabIndex = selectedTabIndex,
modifier = Modifier.fillMaxWidth(), // Don't specify the TabRow's height!
backgroundColor = Colors.White
) {
listOf("Hello", "World").forEachIndexed { i, text ->
Tab(
selected = selectedTabIndex == i,
onClick = { selectedTabIndex = i },
modifier = Modifier.height(50.dp), // Specify the Tab's height instead
text = { Text(text) }
)
}
}
Solution 2
Force the divider to only draw at the bottom of the layout. This is consistent with the default indicator implementation.
TabRow(
selectedTabIndex = ...,
modifier = Modifier.height(100.dp).fillMaxWidth(),
backgroundColor = Colors.White,
divider = { TabRowDefaults.Divider(Modifier.wrapContentSize(Alignment.BottomStart)) },
) { /* content here */ }
Explanation
From the source code here and here, the default divider has height 1dp. However, the OP is seeing a grey background because the divider is drawing over the whole TabRow!
When you specify a height constraint on a TabRow, the constraint gets passed through to the divider (source code here). The divider therefore takes up the entire height of the TabRow – in OP's case, the divider is a transparent grey colour, so it makes the TabRow look grey. The above solutions have a few different ways to solve the problem:
Removing the divider removes the issue!
TabRows wrap their tabs, so an alternative solution is to give the TabRow height by specifying the tabs' heights rather than the TabRow's.
This forces the divider to ignore the TabRow's height constraint, and instead draw itself at its correct height at the BottomStart position in the TabRow.
You can set color using backgroundColor: Color = MaterialTheme.colors.primarySurface,.
(For Documentation read this)
Sample code below:
#Composable
fun TabRow(
selectedTabIndex: Int,
modifier: Modifier = Modifier,
backgroundColor: Color = MaterialTheme.colors.primarySurface,
contentColor: Color = contentColorFor(backgroundColor),
indicator: (List<TabPosition>) -> Unit = #Composable { tabPositions ->
TabRowDefaults.Indicator(
Modifier.tabIndicatorOffset(tabPositions[selectedTabIndex])
)
},
divider: () -> Unit = #Composable {
TabRowDefaults.Divider()
},
tabs: () -> Unit
): #Composable Unit

How can i add a Toolbar in Jetpack Compose?

I need to add a Toolbar in my Android application with a List like below. I am using Jetpack Compose to create the UI. Below is the composable function i am using for drawing the main view.
#Composable
fun HomeScreenApp() {
showPetsList(dogs = dogData)
}
You can use the TopAppBar.
The best way is to use the Scaffold. Something like:
Scaffold(
topBar = {
TopAppBar(
title = {
Text(text = "TopAppBar")
},
navigationIcon = {
IconButton(onClick = { }) {
Icon(Icons.Filled.Menu,"")
}
},
backgroundColor = ....,
contentColor = ....
)
}, content = {
})
In Jetpack compose Toolbar can be easily implemented by using a Composable function called TopAppBar. You need to place TopAppBar along with your main composable function inside a column.
#Composable
fun HomeScreenApp() {
Column() {
TopAppBar(title = { Text(text = "Adopt Me") }, backgroundColor = Color.Red)
showPetsList(dogs = dogData)
}
}
The above function calls the TopAppBar inside a column followed by your main content view. The TopAppBar function takes in a Text object(Not string) as title. This can also be any Composable function. You can also specify other params like backgroundColor, navigationIcon, contentColor etc. Remember that TopAppBar is just a Composable provided by Jetpack team. It can be your custom function also just in case you need more customization.
Output

Does Android Jetpack Compose support Toolbar widget?

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.

Categories

Resources