Giter Site home page Giter Site logo

Comments (35)

ro-savage avatar ro-savage commented on April 19, 2024 26

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.

kingr avatar kingr commented on April 19, 2024 25

@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.

Palisand avatar Palisand commented on April 19, 2024 17

@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.

Darker avatar Darker commented on April 19, 2024 15

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.

Ehesp avatar Ehesp commented on April 19, 2024 14

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.

FiberJW avatar FiberJW commented on April 19, 2024 13

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.

dantman avatar dantman commented on April 19, 2024 12

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 at 20.
  • 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 of 20. 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 to 24. 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 value StatusBar.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 is 0.
  • 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.

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.

marcos-abreu avatar marcos-abreu commented on April 19, 2024 10

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:

  1. The three navigators (StackNavigator, TabNavigator and DrawerNavigator) have different apis
  2. Applying style to the Navigator through navigationOptions might incur in duplication of code
  3. 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) with tabBarPosition: '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.

DavidBadura avatar DavidBadura commented on April 19, 2024 7

@laxgoalie392 you should use paddingTop instead of marginTop ;-)

{
    headerStyle: {
      paddingTop: Constants.statusBarHeight,
      height: 60 + Constants.statusBarHeight,
    }
}

from react-navigation.

ricardoalcantara avatar ricardoalcantara commented on April 19, 2024 7

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.

Ehesp avatar Ehesp commented on April 19, 2024 7

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.

brentvatne avatar brentvatne commented on April 19, 2024 5

resolved in 1.0.0-beta.26

from react-navigation.

inform880 avatar inform880 commented on April 19, 2024 4

Does anybody have a quick fix for someone running with expo + crna? @carsonwah's fix didn't work for me.

from react-navigation.

brentvatne avatar brentvatne commented on April 19, 2024 3

@awitherow - it will be handled on here, @skevy will work on it soon

from react-navigation.

leethree avatar leethree commented on April 19, 2024 3

It'll be great if SafeAreaView could support translucent status bar on Android.

from react-navigation.

carsonwah avatar carsonwah commented on April 19, 2024 3

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.

marcos-abreu avatar marcos-abreu commented on April 19, 2024 2

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)

screenshot_20170730-133724

from react-navigation.

lyahdav avatar lyahdav commented on April 19, 2024 1

@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.

dantman avatar dantman commented on April 19, 2024 1

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.

laxgoalie392 avatar laxgoalie392 commented on April 19, 2024 1

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.

leethree avatar leethree commented on April 19, 2024 1

@JuanCAlpizar SafeAreaView was introduced in #2833 to support iPhone X paddings. Also see this comment from @davepack :
#2889 (comment)

from react-navigation.

ken0x0a avatar ken0x0a commented on April 19, 2024 1

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.

raarts avatar raarts commented on April 19, 2024

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:

screen shot 2017-05-30 at 22 42 17

from react-navigation.

awitherow avatar awitherow commented on April 19, 2024

@brentvatne is there a corresponding PR for this in Expo or is the work going to be handled here?

from react-navigation.

awitherow avatar awitherow commented on April 19, 2024

I see that there are solutions such as

#1168 (comment)

and #1168 (comment) but this is not very optimal.

from react-navigation.

Palisand avatar Palisand commented on April 19, 2024

@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.

Palisand avatar Palisand commented on April 19, 2024

@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.

ricardoalcantara avatar ricardoalcantara commented on April 19, 2024

@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.

FMCorz avatar FMCorz commented on April 19, 2024

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.

JuanCAlpizar avatar JuanCAlpizar commented on April 19, 2024

@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.

carsonwah avatar carsonwah commented on April 19, 2024

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.

carsonwah avatar carsonwah commented on April 19, 2024

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.

abhishek0058 avatar abhishek0058 commented on April 19, 2024

+1

from react-navigation.

kembala avatar kembala commented on April 19, 2024

I can confirm it is definitely still an issue! same here with CRNA

from react-navigation.

brentvatne avatar brentvatne commented on April 19, 2024

@Darker @kemenesbalazs - can you elaborate in a new issue? thanks!

from react-navigation.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.