In Expo we use a translucent StatusBar by default on Android, and some normal React Native projects may do this as well because it makes it easier to reason about cross-platform since the iOS StatusBar is always translucent.
We may need to upstream a constant to React Native that we can use to check if the StatusBar is translucent, and then add any necessary paddingTop to the navigation bar when it is.
I just wanna +1 this because I just used react-navigation for the first time (with Exponent) and realized that I needed to handle android statusbar paddingTop unlike when I use ex-navigation where it handles it for me. It would be really nice for new users to get that functionality out of the box 👍🏿
@lyahdav Here’s a few ways you can do it.
TabNavigator
Pass a second argument to the a Navigator with a custom config containing styles.
Docs
const BasicApp = TabNavigator({ Home : { screen: Home }, Manufacturers : { screen: Manufacturers }, }, { tabBarOptions: { style: { backgroundColor: 'orange', marginTop: 24 }, } });
StackNavigator
Inside a Screen add a header config containing your styles to navigationOptions.
Docs
static navigationOptions = { title: 'something else', header: { style: { backgroundColor: 'orange', marginTop: 24 } } }
DrawerNavigator
No example, but it also takes a second argument with a config where you can add styles.
Docs
The way I’ve been going for now is to have the statusBar as always transparent, with a color of transparent:
In the styles for the navigators, add the following. It allows for a different header color (Android):
EDIT: Seems this only works with TabNavigator for now.
@laxgoalie392 you should use paddingTop instead of marginTop 😉
@awitherow – it will be handled on here, @skevy will work on it soon
@DavidBadura Why are you using 60 instead of 56 for height? I ask because react-navigation’s APPBAR_HEIGTH constant is 56 for android.
Until skevy resolves this issue, I am using:
I’m web developer with a good experience in react, but completely new to
react native
and to native mobile development.When implementing my first project using
create-react-native-app
and using expo to test/debug my app as I develop, I’m facing the same problem as others described in this thread and from what I read here the general understanding is that people are trying to solve it from the perspective ofreact-navigation
and by doing so incurring in various problems:StackNavigator
,TabNavigator
andDrawerNavigator
) have different apisnavigationOptions
might incur in duplication of codeTabNavigator
to stick to the bottom (event for android) withtabBarPosition: 'bottom'
as documented, and all the solutions above seem to expect it on the top (default on android)My solution was to separate the concerns…
and here is my
app-navigation.js
This address all the issues for me, and I can use different navigators, or position them top or bottom and my status bar will be position and styled as expected. In the future if I want to modify the style (such as
backgroundColor
) as I navigate through the tabs I would try to extract the:into its own component and use the react ways of component communication (props and callbacks) to perform any necessary changes.
Since I’m new would love to know if this is a good solution or if not the reasons why it might not be.
For Expo users looking for a simple code sample to make sure content appears under the status bar.
On Android, to get this working really nicely I did the following:
Edit android/app/src/main/res/values/styles.xml
Note: #1e000000 = rgba(0, 0, 0, 0.3)
This makes the statusBar (and bottom navigation bar (soft keys) if present/needed) transparent.
Now on each screen which uses the
navigationOptions
I add in the following:This now makes your Header act as normal, however your StatusBar area is actually transparent with a black opacity over the top. This now allows you to do what you want; change colors dynamically, have an image behind it etc.
Getting the correct status bar underlap height is actually pretty complex.
20
which is correct for all currently released iOS devices. It can grow during calls due to the call indicator, however iOS actually pushes the viewport down clipping the bottom of the viewport instead of growing the status bar’s height, so the relevant height stays at20
.44
. And they’re doing this alongside a release of an iPhone 8 that has as StatusBar height of20
. So iOS’ StatusBar height is now hardware dependent.25
up till Marshmallow (API level 23) when it changed to24
. Some devices like the Kindle Fire change the value. And it’s also dynamic, on tablets it can be 32px. Though as long as there is no circumstance where the"status_bar_height", "dimen", "android"
trick doesn’t return a valueStatusBar.currentHeight
takes care of this for Android.0
.react-native
on Android with no StatusBar tweaks, the StatusBar is not translucent and the overlapping height is0
.react-native
supports android all the way back to API level 16. Whether the StatusBar is translucent if you set it depends on the version of Android and how you set it to translucent.android:windowTranslucentStatus
in KitKat (API level 19), this is how Expo does it.<StatusBar translucent />
does it.I think the long term solution is going to be to make react-native support
StatusBar.currentHeight
on all platforms and add anStatusBar.isTranslucent()
+ event emitter api.By the way, just to make everyone’s lives worse😉 . For awhile now Android’s soft keys (the back/home/recents buttons at the bottom of the screen which are software based on some devices) have had the ability to set them as translucent as well; which is fine since that’s only a problem if the app author does it (at which point they may complain about bottom aligned tabs). Except, the new iPhone X now has a soft home indicator instead of the home button which underlaps just like the StatusBar, and that underlapping footer is mandatory. And just to rub salt in that, in landscape mode you also need to inset from the edges of the screen, except this horizontal inset should be done in your content instead of the views that contain them (so things like dividers still span to the edges).
So a
<NavigationFooter />
api for soft keys and the soft home indicator that works like the proposed StatusBar API will probably be a good idea as well. And then something else to deal with the horizontal insets. Maybe something higher level as well like<StatusBar.Spacer />
to make this easy to deal with.It’ll be great if SafeAreaView could support translucent status bar on Android.
I have found a quick inline fix to the android translucent status bar in stacknavigator.
The syntax is from es6, which works just like Object.assign. Without using this, there will be 3 types of styles to check and set separately (iphone, iphone x, android).
There are currently 2 pull requests trying to fix this:
#2446
#3036
resolved in 1.0.0-beta.26
Does anybody have a quick fix for someone running with expo + crna? @carsonwah‘s fix didn’t work for me.
Why is this closed when the issue is not properly resolved? I just started an Expo app and it definitely does not play nicely with the top bar.