Jetpack Compose TopAppBar wrong color - android

I'm trying to have a white top app bar using Jetpack Compose but the color is grey instead of white.
Here is my code:
#Composable
fun AppTheme(content: #Composable () -> Unit) {
MaterialTheme(
colors = Colors(
primary = colorResource(R.color.colorPrimary),
primaryVariant = colorResource(R.color.colorPrimaryVariant),
secondary = colorResource(R.color.colorSecondary),
secondaryVariant = colorResource(R.color.colorSecondaryVariant),
background = colorResource(R.color.white),
surface = colorResource(R.color.white),
error = colorResource(R.color.failure),
onPrimary = colorResource(R.color.colorOnPrimary),
onSecondary = colorResource(R.color.colorOnSecondary),
onBackground = colorResource(R.color.colorOnBackground),
onSurface = colorResource(R.color.colorOnSurface),
onError = colorResource(R.color.white),
isLight = false
),
typography = Typography(),
shapes = Shapes(),
content = content
)
}
#Composable
#Preview
fun TestTopBar() {
AppTheme {
TopBar(title = R.string.common_country, actions = actions())
}
}
#Composable
fun actions(): #Composable RowScope.() -> Unit = {
IconButton(onClick = {}) { Icon(Icons.Filled.Search, "Search") }
}
#Composable
fun TopBar(title: Int, actions: #Composable (RowScope.() -> Unit) = {}) {
TopAppBar(backgroundColor = Color.White) {
//CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.high) {
Box {
// navigation icon
Row(Modifier.align(Alignment.CenterStart), verticalAlignment = Alignment.CenterVertically) {
IconButton(onClick = { }) {
Icon(Icons.Filled.ArrowBack, "Back")
}
}
// title
Row(Modifier.fillMaxSize(), verticalAlignment = Alignment.CenterVertically) {
Text(
modifier = Modifier
.fillMaxWidth()
.alpha(1f),
textAlign = TextAlign.Center,
maxLines = 1,
text = stringResource(title),
style = MaterialTheme.typography.h6
)
}
// actions
Row(
Modifier.align(Alignment.CenterEnd),
horizontalArrangement = Arrangement.End,
verticalAlignment = Alignment.CenterVertically,
content = actions
)
}
//}
}
}
I've set the surface as white in my theme. I've also set the background color of the top app bar as white. Still, the preview display a light grey instead of white.

Related

Specific Text need Surface in order to be light in Dark mode

I have a sample which I use Jetpack compose in it : https://github.com/alirezaeiii/SampleCompose
Here is my Theme for the application which is the default by Android Studio :
#Composable
fun ComposeTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: #Composable() () -> Unit) {
val colors = if (darkTheme) {
DarkColorPalette
} else {
LightColorPalette
}
MaterialTheme(
colors = colors,
typography = Typography,
shapes = Shapes,
content = content
)
}
Base on this when I am in dark mode, Text's color are light. as an example Texts in my List items:
#Composable
fun VerticalListItem(item: Poster, callback: OnClickListener) {
val typography = MaterialTheme.typography
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
.clickable(onClick = { callback.onClick(item) })
) {
ImageView(url = item.poster, height = 150.dp)
Spacer(Modifier.height(16.dp))
Text(
text = item.name,
style = typography.h6
)
Text(
text = item.release,
style = typography.body2
)
Text(
text = item.playtime,
style = typography.subtitle2
)
}
}
I have a DetailView as follow :
#Composable
fun DetailView(item: Poster, pressOnBack: () -> Unit, sendNotification: () -> Unit) {
val typography = MaterialTheme.typography
Column(
modifier = Modifier
.verticalScroll(rememberScrollState())
.fillMaxHeight()
) {
Box {
ImageView(url = item.poster, height = 420.dp)
Icon(
imageVector = Icons.Filled.ArrowBack,
tint = Color.White,
contentDescription = null,
modifier = Modifier
.padding(12.dp)
.clickable(onClick = pressOnBack)
)
}
Spacer(Modifier.height(8.dp))
Button(
onClick = sendNotification,
modifier = Modifier.align(Alignment.CenterHorizontally)
) {
Text(text = "DeepLink")
}
Spacer(Modifier.height(8.dp))
Surface {
Text(
modifier = Modifier.padding(8.dp),
text = item.description,
style = typography.body2
)
}
}
}
As you see Text here is surrounded by Surface, otherwise it will be Dark in Dark mode. Why is that? Why my other Texts for instance in VerticalListItem do not need Surface? I also have a Button in DetailView which is showing Light in Dark mode. I can not understand why this specific Text need Surface.
The tint is derived from the parent content color. The box is not a surface, has no background so the content color is indifferent. Anyway you don't have to wrap it in a surface, just set the color for the text:
MaterialTheme.colors.onSurface
or
color = contentColorFor(background)

transparent navigation bar leaves a dark box

#Composable
fun BottomNavigationBar(items: List<BottomNavItem>, navController: NavController, onItemClick: (BottomNavItem) -> Unit){
val selectedScreen = navController.currentBackStackEntryAsState()
BottomNavigation(
modifier = Modifier.fillMaxWidth(),
backgroundColor = Color.Transparent,
) {
items.forEach { item ->
val selected = item.route == selectedScreen.value?.destination?.route
BottomNavigationItem(
selected = selected,
onClick = { onItemClick(item) },
selectedContentColor = colorResource(id = R.color.button_background_light_blue),
unselectedContentColor = Color.Gray,
icon = {
Column(horizontalAlignment = CenterHorizontally) {
Icon(imageVector = item.icon, contentDescription = item.name)
if(selected) {
Text(text = item.name, textAlign = TextAlign.Center, fontSize = 10.sp)
}
}
}
)
}
}
}
tbh I haven't found anything about (that's just what I assume) a box that contains icons or anything close to that, what could I add to remove that "box"?
Just set the elevation to 0.dp. I don't know the exact method for BottomNavigation, but if there is a parameter named elevation, set it to 0.dp. If there is no parameter value with that name, apply the elevation Modifier.
Modifier.elevation(0.dp)

How to reduce horizontal space between navigation icon and title in a jetpack compose `TopAppBar`?

I'm making an app bar in jetpack compose but I'm having spacing issues between the navigation icon and the title.
This is my compose function:
#Composable
fun DetailsAppBar(coin: Coin, backAction: () -> Unit) {
TopAppBar(
navigationIcon = {
IconButton(onClick = { backAction() }) {
Icon(
imageVector = Icons.Filled.ArrowBack,
contentDescription = null
)
}
},
title = { Text(text = "${coin.rank}. ${coin.name} (${coin.symbol})") }
)
}
This is my preview function:
#Composable
#Preview
fun DetailsAppBarPreview() {
val bitcoin = Coin(
id = "",
isActive = true,
name = "Bitcoin",
rank = 1,
symbol = "BTC"
)
DetailsAppBar(coin = bitcoin, backAction = {})
}
This is the visual preview of my compose function:
This is the space I want to reduce:
Entering the code of the TopAppBar compose function I can't see any parameters that allow me to do this.
You are right. With the variant of TopAppBar you are using, this is not possible. This is because the width of the NavigationIcon is set to the default (72.dp - 4.dp). You can check the implementation of TopAppBar and see that it uses the below:
private val AppBarHorizontalPadding = 4.dp
// Start inset for the title when there is a navigation icon provided
private val TitleIconModifier = Modifier.fillMaxHeight()
.width(72.dp - AppBarHorizontalPadding)
What you could do is to use the other variant of the TopAppBar that gives you much more control in placing the title and icon. It could be something like:
#Composable
fun Toolbar(
#StringRes title: Int,
onNavigationUp: (() -> Unit)? = null,
) {
TopAppBar(backgroundColor = MaterialTheme.colors.primary) {
Row(
modifier = Modifier
.fillMaxWidth()
.height(56.dp)
) {
// Title
Text(...)
// Navigation Icon
if (onNavigationUp != null) {
Icon(
painter = painterResource(id = R.drawable.ic_back),
contentDescription = stringResource(
id = R.string.back
),
tint = MaterialTheme.colors.onPrimary,
modifier = Modifier
.clip(MaterialTheme.shapes.small)
.clickable { onNavigationUp() }
.padding(16.dp)
...... ,
)
}
}
}
}
Actually it is possible to reduce space between icon and and title but it's a little bit tricky. Just add negative offset to modifier of text like that
#Composable
fun DetailsAppBar(coin: Coin, backAction: () -> Unit) {
TopAppBar(
navigationIcon = {
IconButton(onClick = { backAction() }) {
Icon(
imageVector = Icons.Filled.ArrowBack,
contentDescription = null
)
}
},
title = {
Text(
text = "${coin.rank}. ${coin.name} (${coin.symbol})",
modifier = Modifier.offset(x = (-16).dp)
)
}
)
}

LazyColumn items draw on top of each other

I was using Jetpack Compose version 1.0.0-alpha01 and LazyColumnFor to display some items in a list. After updating to 1.0.0-beta06 I noticed that LazyColumnFor had been deprecated in favor of LazyColumn. After migrating however, the items in the list draw on top of each other instead of being listed vertically with some spacing in between.
What's odd here is that the Preview renders the items as expected, while the app installed on the device(s) does not.
Here's the activity:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val textStyle = TextStyle(color = Color.White, fontSize = 16.sp)
val boldStyle = textStyle.merge(TextStyle(fontWeight = FontWeight.Bold))
ComposeListTestTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
LazyColumn(modifier = Modifier.fillMaxHeight()) {
items(listOf("Row1", "Row2")) { day ->
Text(
text = day,
style = boldStyle,
modifier = Modifier.padding(top = 8.dp),
color = Color.Green
)
}
}
}
}
}
}
}
And here's the preview:
#Preview(showBackground = true)
#Composable
fun DefaultPreview() {
val textStyle = TextStyle(color = Color.White, fontSize = 16.sp)
val boldStyle = textStyle.merge(TextStyle(fontWeight = FontWeight.Bold))
ComposeListTestTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
LazyColumn(modifier = Modifier.fillMaxHeight()) {
items(listOf("Row1", "Row2")) { day ->
Text(
text = day,
style = boldStyle,
modifier = Modifier.padding(top = 8.dp),
color = Color.Green
)
}
}
}
}
}
Unfortunately I haven't been able to get the new layout inspector to work on any of my devices, or I suspect I could've seen some clues as to why this happens.
ComposeListTestTheme:
#Composable
fun ComposeListTestTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
content: #Composable() () -> Unit
) {
val colors = if (darkTheme) {
DarkColorPalette
} else {
LightColorPalette
}
MaterialTheme(
colors = colors,
typography = Typography,
shapes = Shapes,
content = content
)
}
The issue happened because the app was not hardware accelerated. This was fixed in https://issuetracker.google.com/issues/187853238.

fitsSystemWindows counterpart in jetpack compose

I have a transparent status/navigation bars, and when I place a compose element with default layout(top/left), it's placed under the status bar. In xml I use fitsSystemWindows to fix this, how can I get same effect in jetpack compose?
This works for me, In Activity I have :
WindowCompat.setDecorFitsSystemWindows(window, false)
setContent {
JetpackComposePlaygroundTheme {
val controller = rememberAndroidSystemUiController()
CompositionLocalProvider(LocalSystemUiController provides controller) {
ProvideWindowInsets {
ComposeAppPlayground()
}
}
}
}
Then In compose app playground I have something like this:
Surface {
var topAppBarSize by remember { mutableStateOf(0) }
val contentPaddings = LocalWindowInsets.current.systemBars.toPaddingValues(
top = false,
additionalTop = with(LocalDensity.current) { topAppBarSize.toDp() }
)
Column(modifier = Modifier.navigationBarsPadding().padding(top = contentPaddings.calculateTopPadding())) {
// content can go here forexample...
// if you want the content go below status bar
// you can remove the top padding for column
}
InsetAwareTopAppBar(
title = { Text(stringResource(R.string.home)) },
backgroundColor = MaterialTheme.colors.surface.copy(alpha = 0.9f),
modifier = Modifier
.fillMaxWidth()
.onSizeChanged { topAppBarSize = it.height }
)
}
}
Also the InsetAwareTopAppBar I found from guids mentioned in https://google.github.io/accompanist/insets/
#Composable
fun InsetAwareTopAppBar(
title: #Composable () -> Unit,
modifier: Modifier = Modifier,
navigationIcon: #Composable (() -> Unit)? = null,
actions: #Composable RowScope.() -> Unit = {},
backgroundColor: Color = MaterialTheme.colors.primarySurface,
contentColor: Color = contentColorFor(backgroundColor),
elevation: Dp = 4.dp
) {
Surface(
color = backgroundColor,
elevation = elevation,
modifier = modifier
) {
TopAppBar(
title = title,
navigationIcon = navigationIcon,
actions = actions,
backgroundColor = Color.Transparent,
contentColor = contentColor,
elevation = 0.dp,
modifier = Modifier
.statusBarsPadding()
.navigationBarsPadding(bottom = false)
)
}
}

Categories

Resources