I have a screen, which contains a Map and I want to make a statusBar completely transparent.
What I've tried:
implementation "com.google.accompanist:accompanist-systemuicontroller:0.26.1-alpha"
#Composable
fun MapMainScreen() = Column(
modifier = Modifier.fillMaxSize()
) {
val controller = rememberSystemUiController()
controller.setStatusBarColor(color = Color.Transparent)
controller.setNavigationBarColor(color = Color.Transparent)
controller.setSystemBarsColor(color = Color.Transparent)
Map()
}
Also, I've tried to play with window in MainActivity before and in setContent call:
WindowCompat.setDecorFitsSystemWindows(window, false)
window.setFlags(
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,
WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
)
I want to see a result like in Google Maps, but now my statusBar has a White-Gray color instead of Transparent
How can I fix this and make my statusBar Transparent?
Any additional dependency is not needed.
In your Compose theme (or directly in activity) set this:
SideEffect {
with(view.context as Activity) {
WindowCompat.setDecorFitsSystemWindows(window, false)
WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = !darkTheme
window.statusBarColor = Color.Transparent.toArgb()
window.navigationBarColor = Color.Transparent.toArgb()
}
}
Optionally, you could also add this line to make the navigation bar transparent:
window.navigationBarColor = Color.Transparent.toArgb()
This is what Accompanist suggests in the doc:
// Remember a SystemUiController
val systemUiController = rememberSystemUiController()
val useDarkIcons = !isSystemInDarkTheme()
DisposableEffect(systemUiController, useDarkIcons) {
// 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
)
// setStatusBarColor() and setNavigationBarColor() also exist
onDispose {}
}
Also the latest version is : 0.26.3-beta
Related
I want to implement transparent status bar in jetpack compose.
I have integrated the Accompanist library for this but it has no transparent effect on status bar.
implementation "com.google.accompanist:accompanist-systemuicontroller:0.18.0"
// Remember a SystemUiController
val systemUiController = rememberSystemUiController()
val useDarkIcons = !isSystemInDarkTheme()
DisposableEffect(systemUiController, useDarkIcons) {
// Update all of the system bar colors to be transparent, and use
// dark icons if we're in light theme
systemUiController.setStatusBarColor(
color = Color.Transparent,
darkIcons = useDarkIcons
)
// setStatusBarColor() and setNavigationBarColor() also exist
onDispose {}
}
Tried this as well, but it has problem with the gesture navigation
val view = LocalView.current
if (!view.isInEditMode) {
SideEffect {
val window = (view.context as Activity).window
val insets = WindowCompat.getInsetsController(window, view)
window.statusBarColor = Color.Transparent.toArgb() // choose a status bar color
window.navigationBarColor = Color.Transparent.toArgb() // choose a navigation bar color
insets.isAppearanceLightStatusBars = !useDarkTheme
insets.isAppearanceLightNavigationBars = !useDarkTheme
}
}
Kindly suggest a better solution for the transparent status bar.
You have to enable full-screen mode to draw under statusbar:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
WindowCompat.setDecorFitsSystemWindows(window, false)
}
And you can use WindowInsets to avoid drawing under "System gestures":
ViewCompat.setOnApplyWindowInsetsListener(view) { view, windowInsets ->
val insets = windowInsets.getInsets(
WindowInsetsCompat.Type.systemGestures()
)
view.updatePadding(
insets.left,
insets.top,
insets.right,
insets.bottom
)
WindowInsetsCompat.CONSUMED
}
For more information, look at the documentation
Try This
Add the below line to your Theme
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
after adding this line to the theme set this theme in your activity in which you want to set a transparent status bar
Your activity/container layout you wish to have a transparent status bar needs this property set:
android:fitsSystemWindows="true"
add in activity root layout
I'm using the Accompanist systemUiController library and I'm setting
darkIcons=false
while in Light Theme but the effect doesn't apply on devices with android 11. It seems to work on devices with android 10 for example.
This is the code with which I'm trying to set the colors.
val systemUiController = rememberSystemUiController()
systemUiController.setStatusBarColor(color=statusBarColor,darkIcons=false)
where statusBarColor is a darker color which represents the reason I want white foreground/icons
While in Dark Theme it works to set darkIcons
to both true and false and the effect applies accordingly
This is the status bar on LightTheme with darkIcons=false and darkIcons=true
This is the status bar on DarkTheme with darkIcons=false
This is the status bar on DarkTheme with darkIcons=true
For reference this is my whole Theme.kt
private val LightBase = ASBTheme(
material = lightColors(
background = FigmaPrimaryWhite,
onBackground = FigmaTextBlack,
surface = FigmaPrimaryWhite,
onSurface = FigmaTextBlack,
primary = FigmaSecondaryAvastBlue,
error = FigmaStatusPink,
),
textColorLabel = FigmaSecondaryAvastPurple,
colorAccent = FigmaPrimaryGreen,
... //bunch of custom colors
)
private val DarkBase = ASBTheme(
material = darkColors(
background = FigmaPrimaryBlackBg,
onBackground = FigmaTextWhite,
surface = FigmaSecondaryAvastBlueDark,
onSurface = FigmaTextWhite,
primary = FigmaSecondaryBlackDark,
error = FigmaStatusPink
),
textColorLabel = FigmaSecondaryAvastPurpleBright,
colorAccent = FigmaStatusGreen,
... //bunch of custom colors
)
private val LocalAsbTheme = staticCompositionLocalOf { LightBase }
var navBarColor: Color? = null
var statusBarColor: Color? = null
#Composable
fun ASBTheme(
darkTheme: Boolean = isSystemInDarkTheme(),
content: #Composable () -> Unit
) {
val colors = if (darkTheme) {
DarkBase
} else {
LightBase
}
if (darkTheme) {
navBarColor = DarkBase.background
statusBarColor = DarkBase.primary
} else {
navBarColor = LightBase.background
statusBarColor = LightBase.primary
}
SetBarsTheme(statusBarColor!!, navBarColor!!)
CompositionLocalProvider(
LocalAsbTheme provides colors,
) {
MaterialTheme(
colors = colors.material,
content = content,
)
}
}
val MaterialTheme.asbTheme: ASBTheme
#Composable
#ReadOnlyComposable
get() = LocalAsbTheme.current
SetBarsTheme() is where I'm trying to set the status bar colors depending on the lifecycle event so that the colors would maintain after onPause() / onStop(). I also tried to set the colors outside of this logic and the bug still persists.
#Composable
fun SetBarsTheme(
statusBarColor: Color,
navigationBarColor: Color,
darkIcons:Boolean=false,
) {
val lifecycleOwner = LocalLifecycleOwner.current
val systemUiController = rememberSystemUiController()
DisposableEffect(lifecycleOwner) {
// Create an observer that triggers our remembered callbacks
// for sending analytics events
val observer = LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_RESUME) {
systemUiController.setStatusBarColor(color=statusBarColor,darkIcons)
systemUiController.setNavigationBarColor(color=navigationBarColor)
}
}
// Add the observer to the lifecycle
lifecycleOwner.lifecycle.addObserver(observer)
// When the effect leaves the Composition, remove the observer
onDispose {
lifecycleOwner.lifecycle.removeObserver(observer)
}
}
}
There's a fixed bug, make sure you're using the latest Accompanist version.
If you still able to reproduce it, you should report it, including used device/dependencies versions.
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()
I want AppBar to display default shadow below bottom edge but appbar clips its shadow for some reason:
View hierarchy captured from LayoutInspector:
My code:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyAppTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = Color.Cyan,
) {
Box {
TopAppBar(
title = { Text("AppBar title") }
)
}
}
}
}
}
}
Why AppBar shadow behave like this? Am I using it incorrectly? How can I fix this?
UPD:
My bad - shadow works as expected. I just didn't check it properly. Default shadow is very hard to detect visually:
Try to add to Box this code modifier = Modifier.fillMaxSize(). Box cuts your shadow in your code
Example (I added there a white color to see the shadow better)
Surface(
modifier = Modifier.fillMaxSize(),
color = Color.White,
) {
Box(modifier = Modifier.fillMaxSize()) {
TopAppBar(
backgroundColor = Color.White,
title = { Text("AppBar title") }
)
}
}
Result
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(),