Reputation: 78439
I've implemented the pinned
top app bar scroll container, and it works for changing the app bar color on scroll, however the status bar color isn't affected at all.
Here's what I have:
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior(rememberTopAppBarState())
Scaffold(
Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
topBar = {
// just a wrapper for CenterAlignedTopAppBar
StandardTopAppBar("Home", scrollBehavior = scrollBehavior)
}
){ ... }
If it's relevant, in order to detect if the soft keyboard is present, I enabled:
WindowCompat.setDecorFitsSystemWindows(window, false)
And my status bar color in initially set in my Theme
. It was set to primary color when I autogenerated the project in android studios, but I changed it to surface color to match the appbar standards:
if (!view.isInEditMode) {
SideEffect {
(view.context as Activity).window.statusBarColor = colorScheme.surface.toArgb()
//(view.context as Activity).window.statusBarColor = colorScheme.primary.toArgb()
ViewCompat.getWindowInsetsController(view)?.isAppearanceLightStatusBars = !darkTheme // changed from just darkTheme
}
}
tl;dr; top app bar color changes on scroll, but status bar does not. What is the correct pattern to use here? I looked through some of the pinnedScrollBehavior
code, and I don't see anything that would invoke status bar changes, so I'm wondering if I'm supposed to have the status bar be transparent and change the insets for the appbar? Or should I manually hook into the scroll logic and change the color myself? Any help is appreciated!
Upvotes: 6
Views: 3166
Reputation: 91
This is the problem i had until i found this solution here : I used a Scaffold composable, which eccepts : an appBar, content, bottom bar etc . in the scaffold , i added the following :
Scaffold(
topBar = {
TopAppBar(
title = { Text(text = "#Composers", color =
MaterialTheme.colorScheme.primary)
},
modifier=
Modifier.background(MaterialTheme.colorScheme.primary),
scrollBehavior= scrollBehavior
)
},
contentWindowInsets = ScaffoldDefaults
.contentWindowInsets
.exclude(WindowInsets.navigationBars)
.exclude(WindowInsets.ime)
) {
/* Your Scaffold composable content here, for example in my case , i had the following Column */
paddingValues ->
Column(
Modifier
.fillMaxSize()
.padding(paddingValues)
.imePadding()
.systemBarsPadding()
){
/* Your Column composable content chere,*/
}
}
By doing so , the App bar will be adjusted to ensure that it also appears below the status bar making the color appear on nested scroll behaviour.
Upvotes: 1
Reputation: 439
In Theme.kt
, inside the YourAppTheme()
function add.
WindowCompat.setDecorFitsSystemWindows(window, false)
Doing this will display contents below StatusBar and NavigationBar* ( Only on older versions of Jetpack Compose. In newer versions, PaddingValues are correctly set by default. ).
Now set the StatusBar and NavigationBar color to Color.Transparent.
// make sure to use the compose color package, not the default one
import androidx.compose.ui.graphics.Color
window.statusBarColor = Color.Transparent.toArgb()
window.navigationBarColor = Color.Transparent.toArgb()
You also need to make sure that the padding values for the direct child of Scaffold()
are correctly set using the padding values passed in the callback from the Scaffold()
composable.
Set the correct StatusBar
and NavigationBar
icon colors for the theme.
WindowCompat.getInsetsController(window, window.decorView).isAppearanceLightStatusBars = !darkTheme
WindowCompat.getInsetsController(window, window.decorView).isAppearanceLightNavigationBars = !darkTheme
If you're using ModalBottomSheetLayout
or BottomSheetScaffold
, you also need to set Insets inside your BottomSheet composable to prevent NavigationBar
from overlapping app content using,
Modifier.windowInsetsPadding(WindowInsets.navigationBars)
Edit
In Material3, window.setDecorFitsSystemWindows()
is only compatible > API Level 30.
Use WindowCompat.setDecorFitsSystemWindows(window, false)
for backwards compatibility.
Upvotes: 8