Reputation: 1480
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.
Upvotes: 8
Views: 13155
Reputation: 1146
Following @Abanoub Samir's answer (using
enableEdgeToEdge()
with local view removed) will draw the app content below the status bar as shown below.To resolve this you can use
Modifier.statusBarsPadding()
in your@Composable
component.
The solution
The recommended way to do this without enableEdgeToEdge
is in Theme.kt
inside SideEffect
leveraging WindowInsetsControllerCompat
. Default jetpack compose project template does have this SideEffect
implemented. So, we can edit that section as shown below:
val view = LocalView.current
if (!view.isInEditMode) {
SideEffect {
val window = (view.context as Activity).window
val insetsController = WindowCompat.getInsetsController(window, view)
window.statusBarColor = colorScheme.background.toArgb()
window.navigationBarColor = colorScheme.background.toArgb()
insetsController.isAppearanceLightStatusBars = !darkTheme
insetsController.isAppearanceLightNavigationBars = !darkTheme
}
}
This will produce the output as shown below:
Hope this will be helpful 👍
Upvotes: 0
Reputation: 497
In Jetpack Compose you can make the status bar translucent using the new Edge-To-Edge API since accompanist-systemuicontroller is deprecated.
First, go to your Theme.kt and remove the view part from it (the following part):
// Remove this part
val view = LocalView.current
if (!view.isInEditMode) {
SideEffect {
val window = (view.context as Activity).window
window.statusBarColor = colorScheme.primary.toArgb()
WindowCompat.getInsetsController(window, view).isAppearanceLightStatusBars = darkTheme
}
}
Second, open your activity if it is MainActivity.kt or anything else and enable edge-to-edge on it, as following:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge() // Add this
super.onCreate(savedInstanceState)
// Your composables ...
}
}
Now you can run and see the status bar became translucent.
But here is a tip, by default, calling enableEdgeToEdge() automatically adjusts the system bar style to be transparent and dynamically adapts the icon & text colors based on the device’s current theme (white for dark mode, black for light mode).
So you can control the icon & text colors like this:
// For dark (black) colors
enableEdgeToEdge(
statusBarStyle = SystemBarStyle.dark(
android.graphics.Color.TRANSPARENT,
)
)
// For light (white) colors
enableEdgeToEdge(
statusBarStyle = SystemBarStyle.light(
android.graphics.Color.TRANSPARENT,
android.graphics.Color.TRANSPARENT
)
)
So handle the colors as you needed, leave it default to system or make it light or dark based on your use case.
Upvotes: 8
Reputation: 299
If you haven't gotten a solution to this you can use the accompanist library reference already answered below here
Upvotes: 0
Reputation: 6369
Call WindowCompat.setDecorFitsSystemWindows(window, false)
in Activity.onCreate
. This call requests that your app display behind the system UI. Your app will then be in control of how those insets are used to adjust the UI.
Set android:windowSoftInputMode="adjustResize"
in your Activity's AndroidManifest.xml entry. This setting allows your app to receive the size of the software IME as insets, which you can use to pad and lay out content appropriately when the IME appears and disappears in your app.
<style name="Theme.MyApplication" parent="Theme.Material.DayNight.NoActionBar">
<!--Other app theme properties-->
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:navigationBarColor">@android:color/transparent</item>
</style>
Source and more details: https://developer.android.com/jetpack/compose/layouts/insets
Upvotes: -1
Reputation: 1334
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
Upvotes: 3
Reputation: 358
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
Upvotes: -1