Comments (35)
For Expo users looking for a simple code sample to make sure content appears under the status bar.
const App = StackNavigator({
Home: { screen: HomeScreen },
About: { screen: AboutScreen },
}, {
navigationOptions: { headerStyle: { marginTop: Expo.Constants.statusBarHeight } }
})
from react-navigation.
@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
from react-navigation.
@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:
import {Constants} from "expo";
headerStyle: {
height: Constants.statusBarHeight + (Platform.OS === "ios" ? 44 : 56),
paddingTop: Platform.OS === "ios" ? 20 : Constants.statusBarHeight,
}
from react-navigation.
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.
from react-navigation.
The way I've been going for now is to have the statusBar as always transparent, with a color of transparent:
<StatusBar
backgroundColor={'transparent'}
translucent
/>
In the styles for the navigators, add the following. It allows for a different header color (Android):
tabBarOptions: {
style: {
backgroundColor: 'orange', // Main color
borderTopWidth: 24,
borderTopColor: 'red', // StatusBar color
},
}
EDIT: Seems this only works with TabNavigator for now.
from react-navigation.
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 ππΏ
from react-navigation.
Getting the correct status bar underlap height is actually pretty complex.
- iOS' StatusBar height is normally hardcoded at
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
. - However Apple is releasing a new iPhone X which has a StatusBar height of
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. - Android has different StatusBar heights, it was
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. - However while that's all fine for getting the height of the StatusBar, than doesn't actually tell you if the StatusBar is overlapping (is set to translucent), if it's not translucent than the overlapping height is
0
. - If the user is running vanilla
react-native
on Android with no StatusBar tweaks, the StatusBar is not translucent and the overlapping height is0
. - But even if the user sets the StatusBar to translucent, that doesn't mean that it is actually translucent.
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 introduced the ability to set the StatusBar to translucent statically using
android:windowTranslucentStatus
in KitKat (API level 19), this is how Expo does it. - But it wasn't till Lollipop (API level 21) that it became possible to set it translucent dynamically, the way
<StatusBar translucent />
does it.
- Android introduced the ability to set the StatusBar to translucent statically using
I think the long term solution is going to be to make react-native support StatusBar.currentHeight
on all platforms and add an StatusBar.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.
from react-navigation.
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 of react-navigation
and by doing so incurring in various problems:
- The three navigators (
StackNavigator
,TabNavigator
andDrawerNavigator
) have different apis - Applying style to the Navigator through
navigationOptions
might incur in duplication of code - There are other case scenarios where the solutions proposed above don't work, for example in my case I'm forcing my
TabNavigator
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...
import React from 'react';
import { View, StatusBar, Platform } from 'react-native';
import { Tabs } from './app-navigation';
const App = () => {
return (
<View style={styles.container}>
<View style={styles.statusBar}>
<StatusBar
backgroundColor={'transparent'}
translucent
/>
</View>
<Tabs />
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
},
statusBar: {
height: (Platform.OS === 'ios' ? 20 : StatusBar.currentHeight),
backgroundColor: 'red',
},
});
and here is my app-navigation.js
import React from 'react';
import { TabNavigator } from 'react-navigation';
import Sample1 from './screen/sample1';
import Sample2 from './screen/sample2';
export const Tabs = TabNavigator({
Sample1: {
screen: Sampe1,
},
Sample2: {
screen: Sample2,
},
}, {
tabBarPosition: 'bottom',
});
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:
<View style={styles.statusBar}>
<StatusBar
backgroundColor={'transparent'}
translucent
/>
</View>
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.
from react-navigation.
@laxgoalie392 you should use paddingTop instead of marginTop ;-)
{
headerStyle: {
paddingTop: Constants.statusBarHeight,
height: 60 + Constants.statusBarHeight,
}
}
from react-navigation.
Hey people I might have found a way to solve that problem. I was having a terrible time trying to configure the "keyboard adjustresize" with Textinput and in the expo.io forum I discovered that if you fill the app.json with the field
"androidStatusBar": {
"backgroundColor": "#999999"
}
It not only makes the "keyboard adjustresize" works but also does fix this translucent issue.
Update:
You need only the AndroidStatusBar -> backgroundColor
Update 2:
Remember to close and open the app again, I took so long to realize that I had to kill the app to apply the change.
from react-navigation.
On Android, to get this working really nicely I did the following:
Edit android/app/src/main/res/values/styles.xml
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="android:navigationBarColor">@android:color/transparent</item>
<item name="android:statusBarColor">#1e000000</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
</resources>
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:
headerStyle: {
height: 56 + StatusBar.currentHeight, // 56 = Header/Toolbar spec
paddingTop: StatusBar.currentHeight, // StatusBar height
backgroundColor: 'pink',
}
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.
from react-navigation.
resolved in 1.0.0-beta.26
from react-navigation.
Does anybody have a quick fix for someone running with expo + crna? @carsonwah's fix didn't work for me.
from react-navigation.
@awitherow - it will be handled on here, @skevy will work on it soon
from react-navigation.
It'll be great if SafeAreaView could support translucent status bar on Android.
from react-navigation.
I have found a quick inline fix to the android translucent status bar in stacknavigator.
navigationOptions: {
headerStyle: {
...Platform.OS === 'android' ? { paddingTop: StatusBar.currentHeight, height: StatusBar.currentHeight + 56 } : {},
}
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
from react-navigation.
Hey @Palisand, thanks for replying and reviewing my solution. As for the problems I experienced when testing your solution (specially regarding 3) was that headerStyle
is only available for StackNavigator
(as documented here) but not on TabNavigator
(as documented here) and even if I adjust the styles from your solution to a property that TabNavigatior
accepts it results in something like the image bellow: (I've used the color red to indicate where the style is being applied)
from react-navigation.
@datwheat I ran into this same issue with react-navigation and Exponent. Can you provide an example of your code that fixed this? I'm not understanding where to add the paddingTop. I basically followed the instructions here to use react-navigation.
from react-navigation.
For handling this within react-navigation, it would probably be easiest if control of the statusBar
as a navigation option was implemented in react-navigation first. Then instead of needing to ask for a React Native constant or some other sort of input we could just say that the transparent status bar should be applied using react-navigation's statusBar
props.
from react-navigation.
Any news on this? I could only get the padding doing something like the following and the status bar does not reflect the color of the header
static navigationOptions = {
title: "Welcome",
headerStyle: { marginTop: Constants.statusBarHeight },
};
(Constants
comes from expo)
from react-navigation.
@JuanCAlpizar SafeAreaView was introduced in #2833 to support iPhone X paddings. Also see this comment from @davepack :
#2889 (comment)
from react-navigation.
I'm using
"expo": "^28.0.0",
"react-navigation": "~2.3.1",
With this versions, to avoid navbar height overwrap on ANDROID, I'm using code below.
I hope it helps someone.
const HomeTabScreen = createStackNavigator(
RouteConfig,
{
mode: 'card',
navigationOptions: {
headerTitleAllowFontScaling: true,
...Platform.select({
android: {
headerStyle: {
marginTop: -Expo.Constants.statusBarHeight,
},
},
}),
},
},
)
from react-navigation.
I have the same problem, but in iOS. The given solution works on Android, but not on iOS. Here's my main.js:
import Expo from 'expo';
import React from 'react';
import {
StatusBar,
StyleSheet,
View,
Text,
} from 'react-native';
import { TabNavigator } from "react-navigation";
class RecentChatsScreen extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>List of recent chats!!</Text>
</View>
)
}
}
class AllContactsScreen extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>List of all contacts</Text>
</View>
)
}
}
const styles = StyleSheet.create({
// App container
container: {
flex: 1,
//paddingTop: Expo.Constants.statusBarHeight,
},
});
const MainScreenNavigator = TabNavigator({
Recent: { screen: RecentChatsScreen },
All: { screen: AllContactsScreen },
}, {
tabBarOptions: {
style: {
backgroundColor: 'orange',
marginTop: 24
},
},
});
Expo.registerRootComponent(MainScreenNavigator);
Uncommenting paddingTop in styles.container works, but this moves reponsability for fixing this into each separate screen.
Here's my package.json:
{
"name": "nav-test",
"version": "0.0.0",
"description": "Hello Expo!",
"author": null,
"private": true,
"main": "main.js",
"dependencies": {
"expo": "17.0.0",
"react": "16.0.0-alpha.6",
"react-native": "https://github.com/expo/react-native/archive/sdk-17.0.0.tar.gz",
"react-navigation": "^1.0.0-beta.11"
}
}
On iOS this looks like this:
from react-navigation.
@brentvatne is there a corresponding PR for this in Expo or is the work going to be handled here?
from react-navigation.
I see that there are solutions such as
and #1168 (comment) but this is not very optimal.
from react-navigation.
@marcos-abreu I have a couple months worth of react-native experience and a few more of react. For what it's worth, your solution seems just fine to me. As for why mine wasn't working, I recently made an edit to my answer without remembering that StatusBar.currentHeight
was Android only. I've since re-edited, using Expo's constant instead. Only including a headerStyle
is the probably the fastest way to resolve the header bar height issue, but certainly not the most optimal. However, considering a solution is in the works, I figure there is no need for further improvement just to have it reverted once the official solution is released.
Also, I am not experiencing problem 3 with my posted changes.
from react-navigation.
@marcos-abreu Hmmm... you're absolutely right. My TabNavigator
was nested in a StackNavigator
that had the styles set, which is why it was working for me. So it looks like your solution takes care of most, if not all, issues. The only suggestion I have now is that if you end up extracting the view-wrapped status bar into its own component, you might want to use redux to control its state, considering it is used app-wide.
from react-navigation.
@ro-savage I guess if you go that way, when you need the "keyboard adjustresize" (that auto scroll to the inputfield when the keyboard appear), and you fix with that thing I said, you will get double sized status bar. But it happens only with the new create-native-react-app using expo framework.
from react-navigation.
Is this a terrible idea?
Edit: yes it is.
import { Constants } from 'expo';
const Navigation = StackNavigator({
Home: {
screen: HomeScreen
}
});
export default class App extends React.Component {
render() {
return <Navigation style={{ paddingTop: Constants.statusBarHeight }} />;
}
}
So surely the content will not flow underneath the bar, but at least it saves me from having to add padding to all my screens.
from react-navigation.
@leethree sorry, I just found this when I was trying to find a solution to my status bar problem, but I don't quite understand, whatΒ΄s SafeAreaView, is it some under the hood implementation or do we need to implement it in our current code?
from react-navigation.
This should be a pretty old issue. Is there any update on this?
I was using the following code to fix it (can't remember why 64):
headerStyle: {
// padding height for translucent status bar
height: Platform.OS === "ios" ? 64 : (56 + StatusBar.currentHeight),
paddingTop: Platform.OS === "ios" ? 20 : StatusBar.currentHeight,
}
But it is not working desirably after that iphone x support update. (64 height in ios becomes too large)
Either way I will fix it manually. But I think this should be supported as soon as possible as Expo
is translucent by default as @brentvatne said.
from react-navigation.
I am guessing that the source of the extra height comes from here:
(some updates from 1.0.0-beta.19, or actually 1.0.0-beta.18)
d93acdd#diff-7d1ace708bab0c8203594be64846ebecR47
https://github.com/react-community/react-navigation/releases/tag/v1.0.0-beta.19
Just FYI, for anyone having the same issue after the update.
from react-navigation.
+1
from react-navigation.
I can confirm it is definitely still an issue! same here with CRNA
from react-navigation.
@Darker @kemenesbalazs - can you elaborate in a new issue? thanks!
from react-navigation.
Related Issues (20)
- Sometimes duplicate tab bar labels appear in bottom tabs HOT 1
- unmountOnBlur shows white screen randomly when switchint tabs HOT 2
- useHeaderHeight changes several times when orientation changes HOT 3
- Navigate into page, increase RAM, navigate back and RAM stays high HOT 1
- When using frosted glass stack to jump in Android mode, ReactNavigation will experience lag and frosted glass will reset HOT 5
- Weird transition in navigation HOT 2
- Invariant Violation: requireNativeComponent: "RNSModalScreen" was not found in the UIManager. HOT 16
- [Bridgeless] [RN 0.74] Event cannot be both direct and bubbling: topFocus HOT 4
- Strange flicker when you scroll up a modal with NativeStack in iOS
- Ripple effect shown twice after clicking one time on material top tab after new architecture enabled. HOT 4
- onStateChange called after screen's mount (useEffect) HOT 6
- MaterialTopTabNavigator Icon Layout Shifting HOT 4
- To prevent the default behavior using e.preventDefault() on `tabPress` event is no longer working HOT 4
- RemoveEventListener error in react-native-navigation@4 HOT 7
- Keyboard is dismissed immediately when focusing on TextInput field on non-outer tabs for `react-native-tab-view` HOT 1
- RemoveEventListener error in react-native-navigation@4 HOT 8
- Bottom Tabs flash when opening keyboard HOT 2
- Bottom Tab Navigator falls out of viewable area HOT 2
- Wrong header height value for screens inside Native Stack inside another Native Stack with modal presentation on iOS
- headerLargeTitle: true with headerBackTitleVisible: false makes back button animation jerky HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from react-navigation.