facebook/react-native

[Modal-StatusBar-Android] Statusbar shows up with setHidden(true)

duketwo opened this issue ยท 81 comments

While the modal component is open on an android device with StatusBar.setHidden(true) the StatusBar still shows up.

Is this intended? If yes, is there any workaround?

Edit: On iOS the StatusBar remains hidden when a modal component is open.

Looks like a bug, I never tested StatusBar + Modal, I'll take a look at it when I get some time.

Any idea about this? I lose background color and translucent properties as well. It looks pretty bad.

I have the same problem, iOS works fine indeed

check my comments on #8627 if have any help

Any updates on this?

I have the same problem.

  • ReactNative 0.32
  • Android 6+

Idem, same problem.

RN: 0.34

+1. RN: 0.34

Component 01 (showBar Hide):

componentWillUnmount() {
  StatusBar.setHidden(true)
}

TO

Component 02:

componentWillMount() {
  StatusBar.setHidden(false)
}

result: ShowBar SHOW

But

Component 01 (showBar Hide):

componentWillUnmount() {
  AppActions.showBar(true)
}

TO

Component 02:

componentDidMount() {
  AppActions.showBar(false)
}

result: ShowBar HIDE

Also noticed that if you highlight some text in the modal, the 'Text Selection' menu has a very undesirable transparent look that shows the view below.

Any ideas how to fix this appearance?

Screen shot:

screen shot

It's amazing that this issue was opened the May 9th and nobody still figured out why it has this behaviour!

@scerelli I've answered months ago to see my answer in #8627, so why this issue is still opening?

@nihgwu honestly i don't know, and the fact that you explained the cause of this problem in an other issue it's even stranger.
This fix/feature is not in roadmap at the moment and it's not good at all! it brings a lot of inconsistency inside applications that use a lot of modals and requires the status bar to be hidden.

There are still cases where the statusbar is not updated properly because the activity was null at the time it was updated, I think this happens mostly when moving the app from the background to foreground. I haven't really hit this issue yet since I'm not changing the statusbar much in my apps so I don't have a repro case to try to fix it. If someone wants to spend some time looking into why it happens and possible fixes it would be great.

A quick fix I can think of would be to subscribe to AppState and force an update of the statusbar native values at that time when we are sure the activity is available.

Edit: confused some issues not sure about this one :)

I don't have much time to look into this at the moment, I suspect we'd want to change the dialog window flags to match the current statusbar config. We already set some flags here https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java#L199

To do that we could try to read flags from the main app window and use the same for the modal.

+1 RNv: 0.40

@janicduplessis I already checked this issue. The reason it doesn't work is because WindowInsets is been set to the wrong window. Modal is implemented with Dialog, Dialog will create a window on the top of Activity's Window. So it won't work for now. But I couldn't find a good way to get the Window of Dialog, do you have any idea?

Any news about this issue? Still getting it with RN 0.4.2

I was able to work around this issue by going into my app's android/app/src/main/res/values/styles.xml file and changing the parent theme to Theme.ReactNative.AppCompat.Light.NoActionBar.FullScreen. This essentially disables the status bar by default for your entire app, including for the modal. If you have other screens that need to show the status bar then you can still use the normal StatusBar api to show it if you want.

Here's my full styles.xml file for reference:

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.ReactNative.AppCompat.Light.NoActionBar.FullScreen">
        <!-- Customize your theme here. -->
    </style>
    <style name="AppTheme.Launcher">
        <item name="android:windowBackground">@drawable/launch_screen</item>
    </style>
</resources>

@Traviskn This solution also has a issue, in some time, at bottom of the Modal has a transparent bar , and height equal to StartBar height.

Still happens at 0.43 version.

Any updates?

Mark!

Any updates on this?

Okay So I found a solution for having the hidden status bar along with react native modal.

My previous code was like this :

<View style={styles.container}>
  <StatusBar hidden={true}/>
  <View style={styles.content}>
  <Modal animation={fade} transparent={true}>
          {/*Modal Contents Here*/}
  </Modal>
</View>

This code used to give me issues with UI views outside modal with position absolute and the above mentioned issue with Status Bar which shows up.

Replacing the above code layout into a new one where all the current contents come inside a New container outside helped me overcome both these problems. In my case the new formatted code that works is given below :

<View style={styles.outerContainer}
  <View style={styles.container}>
    <StatusBar hidden={true}/>
    <View style={styles.content}>
  </View>
  <Modal animation={fade} transparent={true}>
          {/*Modal Contents Here*/}
  </Modal>
</View>

Hope this helps whoever is having this issue ๐Ÿบ ๐Ÿบ ๐Ÿบ

I have the same issue , so i hide the status bar from styles.xml using "windowFullscreen" property setting to true, but doing so, at bottom of the Modal has a transparent bar , and height equal to StartBar height.

Any updates on this? Still see the status bar when the modal opens.

"react-native": "0.44.2"

  • Set StatusBar.setHidden(true) in ComponentWillMount() - it is not working.
  • Added StatusBar <StatusBar hidden/> - it is working until the first page refresh

Any time frame by which this issue will be solved? RN 0.47 has been released now!

@RavishankarR, thanks for the reply. I have tried to check it, but 0.47 has changes, which broke many packages. Please take a look lottie-react-native/lottie-react-native#166. When I fix some packages, I can still see that issue. Moreover, a view is jumping as when I visit a page with hidden status bar.

"react-native": "0.44.2"
It is working for me now. The issue was related with navigation and a view updation. But I can see jumping when I moving from some page with status bar to other page, where its status bar is hidden.

@EugeneBichel Could you explain how you got it to work in RN 0.44?

I am trying to hide the statusbar only when opening a modal, which does not work in Android.

Lastly, is there a way to set an offset value to the statusbar?

Also having trouble with this, status bar drops down when a modal appears on Android (ios is fine)! Appreciate any advice/workarounds as we need to get this into the app store for our clients. for example if there is a global setting to stop the status bar showing across the entire app that would be fine in this case (RN 0.44.0)

This is still an issue for me on Android in RN 0.47.1

Update:
Also still an issue in 0.48.0

I fixed a different issue with the StatusBar handling on Android awhile ago.

For anyone interested in trying to fix this issue here is the code responsible for setting the various Android properties on the "Dialog" layer that is opened by Modal.

mDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
if (mHardwareAccelerated) {
mDialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
}
mDialog.show();
}
/**
* Returns the view that will be the root view of the dialog. We are wrapping this in a
* FrameLayout because this is the system's way of notifying us that the dialog size has changed.
* This has the pleasant side-effect of us not having to preface all Modals with
* "top: statusBarHeight", since that margin will be included in the FrameLayout.
*/
private View getContentView() {
FrameLayout frameLayout = new FrameLayout(getContext());
frameLayout.addView(mHostView);
frameLayout.setFitsSystemWindows(true);
return frameLayout;
}
/**
* updateProperties will update the properties that do not require us to recreate the dialog
* Properties that do require us to recreate the dialog should set mPropertyRequiresNewDialog to
* true when the property changes
*/
private void updateProperties() {
Assertions.assertNotNull(mDialog, "mDialog must exist when we call updateProperties");
if (mTransparent) {
mDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
} else {
mDialog.getWindow().setDimAmount(0.5f);
mDialog.getWindow().setFlags(
WindowManager.LayoutParams.FLAG_DIM_BEHIND,
WindowManager.LayoutParams.FLAG_DIM_BEHIND);
}
}

Modal seems to be a layer of its own on top of the main layer/window and I think has it's own set of status bar properties separate from the main ones in the main activity.

Just wondering if anyone has figured out a workaround for this? Looks like it was opened in May, 2016. It's almost November, 2017. Has anyone successfully hid the status bar in on Android?

The solution from @Traviskn worked for me! I don't have any gap at the bottom as some people described.

@Traviskn, Your solution worked for me as well like a charm. Thanks!

@Traviskn solution didn't worked for me, any hint on what I may doing wrong?

Having the same issue, any idea how to fix it ?

@khrizt I'm not sure why it wouldn't be working, are you on a newer version of React Native? It's also important to re-install the application because changing the theme in the styles.xml file is a native change and won't take effect until you actually re-install the app, a simple refresh won't work.

@Traviskn Sorry, I was doing it totally wrong. It works! But the thing now is that I want to hide the status bar only in some modals, but not in all of them, I've tried to add the StatusBar to the Modals but it didn't work, If you have any ideas it'd be great :)

@Traviskn Your work around works. Let us hope there will be a proper fix released soon.

@Traviskn Thanks, it works for me

@Traviskn's solution solved the problem for me perfectly. Thank you.

@Traviskn's solution worked for me but only to hide the status bar. The Navigation bar at the right hand side (landscape mode) is still there. Anyone has a solution for this?

+1 Still an issue.

I don't understand why the modal goes behind the status bar on iOS and not on Android. Very inconsistent and annoying!

Hello,
Here is my solution

  1. Overwrite file <node_modules>\react-native\ReactAndroid\src\main\res\views\modal\values\themes.xml
    themes.xml.txt

  2. cd your project/android
    + change android SDK & NDK path in local.properties file (and/or ANDROID_NDK environment variable)
    local.properties.txt
    + call command:
    gradlew ReactAndroid:installArchives

  3. cd Root Project
    + call command:
    react-native run-android

Hope it helps!
Regards,
LCD

Ref: https://facebook.github.io/react-native/docs/android-building-from-source.html

@lcd11001 I'm using EXPO, and am not in a position to eject, so sadly, that is not an option for me.

@Traviskn solution is functional but when you show a StatusBar on an interface and you open a Modal over it, the statusbar collapses up making all the app body going up 12 pixels, really awkward!
It's weird that when the modal opens it kills the underlying statusbar... ๐Ÿ˜ข

t4deu commented

Hi everyone, just sent a PR with a fix, hope it helps to close this old issue!
@janicduplessis could you please review if everything is ok, anything just let me know, thanks ๐Ÿ˜‰!

I am still facing the same issue. Is there any react-native solution.

@netsmertia the pull request is not approved yet.

Still have the same issue.

t4deu commented

@liuqiang1357 You are building from master? because the fix was not released yet!

@t4deu tried your solution

thx for prevent show a hidden status bar when opening modals,
do u have any idea, prevent statusBar turn white when opening models with statusBar showing

ref๏ผšreact-native-modal/react-native-modal#50
#16103
#16597

here is my solution

/**
   * updateProperties will update the properties that do not require us to recreate the dialog
   * Properties that do require us to recreate the dialog should set mPropertyRequiresNewDialog to
   * true when the property changes
   */
  private void updateProperties() {
    Assertions.assertNotNull(mDialog, "mDialog must exist when we call updateProperties");

    Activity currentActivity = ((ReactContext) getContext()).getCurrentActivity();
    if (currentActivity != null) {
      int activityWindowFlags = currentActivity.getWindow().getAttributes().flags;
      if ((activityWindowFlags
              & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0) {
        // fix show modal when hidden statusBar  โ€”โ€” Prevent show a hidden status bar
        mDialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
      } else {
        mDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        // fix show modal when show statusBar  โ€”โ€” statusBar turn white without text color changed
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
          if ((currentActivity.getWindow().getDecorView().getSystemUiVisibility() & View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR) != 0) {
            mDialog.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
          } else {
            mDialog.getWindow().getDecorView().setSystemUiVisibility(0);
          }
        }
      }
    }

    if (mTransparent) {
      mDialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
    } else {
      mDialog.getWindow().setDimAmount(0.5f);
      mDialog.getWindow().setFlags(
          WindowManager.LayoutParams.FLAG_DIM_BEHIND,
          WindowManager.LayoutParams.FLAG_DIM_BEHIND);
    }
  }

Same issue here ...

Please release the fix.

+1
Please release the fix.

I confirm @Traviskn's workaround works. For modal implemented in https://github.com/beefe/react-native-actionsheet, on Android side.

Pretty incredible this issue is still around, now in RN 0.54.4 for my app, after 2 years.

@janicduplessis It doesn't work.When the Modal show Statubar still apper ! How can I do ?

I confirm @Traviskn 's way too. this workaround may produce some issue at a particular scene(such as you need status bar shows more frequently than hidden), but it still may be the best way to solve modal status bar problem once for all.

can use origin android to resolve it ?

@t4deu I can see the issue with react-native 0.56.0 from Android, any solution to fix the issue of the bottom of the modal?
Thanks in advance

Ok, fixed by using
<style name="AppTheme" parent="Theme.ReactNative.AppCompat.Light.NoActionBar.FullScreen">
instead of
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">

farzd commented

still an issue, using expo so cant change android specific xml files etc

When will you fixed this issue ?

The better solution is to not use the native React Modal. Use this library instead: https://github.com/maxs15/react-native-modalbox

There is still a problem with devices that have a soft menu bar like the Samsung Galaxy S8 and no solution solves the problem with the soft menu bar region not being drawn over by the Modal.

ok,fixed by using
<style name="AppTheme" parent="Theme.ReactNative.AppCompat.Light.NoActionBar.FullScreen"> <item name="android:windowTranslucentStatus">true</item> // ่ฎพ็ฝฎ็Šถๆ€ๆ ไธๅ ๆฎ็ฉบ้—ด </style>

If the theme color is white๏ผŒ fixed by using
<style name="AppTheme" parent="Theme.ReactNative.AppCompat.Light.NoActionBar.FullScreen"> <item name="android:windowLightStatusBar">true</item> // Android 6.0ไปฅไธŠ่ฎพ็ฝฎ็™ฝๅบ•้ป‘ๅญ— </style>

I used https://github.com/listenzz/react-native-modal-translucent, and worked like a charm.

settings.gradle
include ':modal-translucent'
project(':modal-translucent').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-modal-translucent/android')
build.gradle
implementation project(":modal-translucent")
MainApplication
import me.listenzz.modal.TranslucentModalReactPackage;

@Override
protected List<ReactPackage> getPackages() {
    return Arrays.<ReactPackage>asList(new MainReactPackage(), ..., new TranslucentModalReactPackage());
}

@pablobrodt Can you explain to me how did you make it work? I'm getting an error using the package. I've opened there a new issue.

@Jelomite I just linked this https://github.com/listenzz/react-native-modal-translucent manually, like i said above, then used the react-native Modal with transparent prop.

I see, thanks ๐Ÿ˜„

I changed the default Modal implementation of react-native and solved this problem. What I do is to replace the official Modal package with one a-little-modified Modal package which shows Modal in full screen with status bar above, you can refer to https://www.cnblogs.com/wkmcyz/articles/10277436.html for details.

nihp commented

I need to hide the iOS status bar of my app in some screens and not for all screens. Any solution for this.

I tried this but it did not work for me.

<StatusBar hidden={true} />

Still happening in RN 0.60.5.

react-native-modal-translucent solved my problem https://github.com/listenzz/react-native-modal-translucent