-
Notifications
You must be signed in to change notification settings - Fork 24.8k
Add StatusBar height constant and improve implementation #6195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add StatusBar height constant and improve implementation #6195
Conversation
This adds a `HEIGHT` constant on `StatusBar` on Android. I needed only this for now but I will work on a better status bar dimensions API later (see TODO). It also improves the implementation to fix a bug that happened when multiple `StatusBar` components get updated in the same frame as well as remove useless calls to the `StatusBarModule` when values did not change. Instead of calling the `StatusBarManager` immediatly when the component gets updated and relying on the order of the calls that get dispatched to native we now wait at the end of the frame to send the calls to the `StatusBarManager` using `setImmediate`. To make this work properly we need to change the data structure of the props stack a little bit to store the desired transition/animation too for each value. Finally this updates the example to only show the ones that work for the current platform.
By analyzing the blame information on this pull request, we identified @janicduplessis to be a potential reviewer. |
Also this depends on the fix in #6192 |
fyi buck build is broken |
@@ -40,6 +48,19 @@ public String getName() { | |||
return "StatusBarManager"; | |||
} | |||
|
|||
@Override | |||
public @Nullable Map<String, Object> getConstants() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why @Nullable
? Doesn't it always return a Map
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The method in the base class is @Nullable
, I just kept the same signature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should be able to leave off the @Nullable
assuming the return types are covariant (think I have that right)
@bestander Thanks for being the gatekeeper of the buck build, I need to stop forgetting about testing that :) |
@janicduplessis updated the pull request. |
@facebook-github-bot shipit |
Thanks for importing. If you are an FB employee go to Phabricator to review. |
Heads up that on iOS the status bar height isn't a constant and is dynamic. |
@ide Yes, right now it is Android only, I'll try to think of a good API when I get some time that works for both. I was thinking something like an EventEmitter to subscribe to height changes, a function to get the current height (it would return 0 if the status bar is currently hidden for example) and a function to get the 'normal' status bar height that would never change (always ~20 on iOS, ~25 on Android). |
IMO we should not have it as a constant if it's not a constant on both platforms. I agree about having an event and a function returning a promise for the height. |
Yea, it should be something like |
@janicduplessis oops, seems I made a typo in my comment. I meant that we shouldn't have a constant. It makes clear that it can change. |
I think we should have both, the constant has the advantage of being sync so you don't have to rerender a view after receiving the value of the status bar height. And then we can use something like an event listener to update the value of the height if it does change after. |
@janicduplessis It also makes it super easy to use incorrectly. Say someone uses it in SyleSheet.create, and then later the height changes, it means bad UX. And we should try to make it difficult to do bad UX. The current dimensions APIs fall into similar category. They are synchronous and constants, and super easy to forget to update. We should not repeat the same mistakes. If the user needs to access it synchronously, he can always store it in a variable. So we're not really limiting anything. |
Totally agree but I'm not sure if there is a way to keep the convenience of having the value as a constant while forcing users to make sure they update it properly. Even if it's a promise returning the current value, it can still cause issues when the value changes while the view is displayed so it doesn't 100% fix the issue. |
I guess the difference in naming is good enough, It also allows lazy evaluation, without having to set the constant if nobody is using it. That's how most of the RN modules are defined. They aren't initialised until needed, but that's another topic. I think the asynchronous value encourages people to store it in the component state which makes it much easier to update, even though they still have to listen to the events manually, as opposed using it in SyleSheet directly. |
A promise might not be the right API -- as you guys mentioned, the asynchronous aspect is annoying to work with. We could instead offer an API like this: // A read-only property that synchronously provides the last-known height of the status bar
StatusBar.currentHeight
// Maybe we want to provide a richer API:
StatusBar.currentSize.{width, height}
// Get notified when the status bar height changes
StatusBar.addListener('change', ({
size: { width, height },
position: { x, y },
orientation: StatusBar.Orientation.{ LANDSCAPE, PORTRAIT },
animationStyle: StatusBar.AnimationStyle.{ FADE, SLIDE }, //
animationDuration: number,
}) => { ... }); As with this diff, we'd send the initial height of the status bar from native to JS via the StatusBar module's constants, and StatusBar.js would subscribe to changes in the status bar and constantly update the properties like |
Yeah, currentHeight is a better name instead of just HEIGHT as it communicates the fact that it's just the current height. I think @foghina had some suggestions about the Dimensions API, so ccing him. |
Good call about the Dimensions API -- it's not too different from the status bar in a lot of ways. [On that note, we should separate the notions of "physical screen dimensions" (actual device size) from "logical screen dimensions" (device size minus the software nav bar on Android) from "root size" (size of the root React view, which could be any size).] All of these may change over the course of an app's lifetime, especially with multi-screen devices or multi-window iPads, and having a consistent API across all of these would be pretty sweet. |
@ide I like the API you proposed, I try to get a prototype implementation going soonish :) |
Summary:This adds a `HEIGHT` constant on `StatusBar` on Android. I needed only this for now but I will work on a better status bar dimensions API later (see TODO). It also improves the implementation to fix a bug that happened when multiple `StatusBar` components get updated in the same frame as well as remove useless calls to the `StatusBarModule` when values did not change. Instead of calling the `StatusBarManager` immediately when the component gets updated and relying on the order of the calls that get dispatched to native we now wait at the end of the frame to send the calls to the `StatusBarManager` using `setImmediate`. To make this work properly we need to change the data structure of the props stack a little bit to store the desired transition/animation too for each value. Finally this updates the example to only show the ones that work for the current platform. **Test plan** In the UIExplorer Example, in the 'StatusBar dimensions' section it should show 25 for the height of the status bar. A Closes facebook#6195 Differential Revision: D3017559 fb-gh-sync-id: d6f4c6a72a2dfde83496ecc0f56dca4abaf3055e shipit-source-id: d6f4c6a72a2dfde83496ecc0f56dca4abaf3055e
@janicduplessis updated the pull request. |
1 similar comment
@janicduplessis updated the pull request. |
…en over the status bar Summary:The navigation drawer of most apps on android opens over the status bar, this adds an option to do so. It implements a similar API to the native DrawerLayout by adding a statusBarBackgroundColor to DrawerLayoutAndroid. Without statusBarBackgroundColor:  With statusBarBackgroundColor:  This PR depends on the changes in #6195 to add the `StatusBar.HEIGHT` constant I just want to put it out there now to see if this looks good. To test without the other PR just change `StatusBar.HEIGHT` for `25`. It is implemented by making the native status bar translucent and making its background color transparent so we can draw a view of the same height as the status bar under it as a child of the DrawerLayoutAndroid. Then we can draw a semi-transparent gray View inside the drawer view to make it Closes #6218 Differential Revision: D3017444 Pulled By: bestander fb-gh-sync-id: ca48a47a20a2feecae360a76f3e2c9bbe6a37700 fbshipit-source-id: ca48a47a20a2feecae360a76f3e2c9bbe6a37700
…en over the status bar Summary:The navigation drawer of most apps on android opens over the status bar, this adds an option to do so. It implements a similar API to the native DrawerLayout by adding a statusBarBackgroundColor to DrawerLayoutAndroid. Without statusBarBackgroundColor:  With statusBarBackgroundColor:  This PR depends on the changes in #6195 to add the `StatusBar.HEIGHT` constant I just want to put it out there now to see if this looks good. To test without the other PR just change `StatusBar.HEIGHT` for `25`. It is implemented by making the native status bar translucent and making its background color transparent so we can draw a view of the same height as the status bar under it as a child of the DrawerLayoutAndroid. Then we can draw a semi-transparent gray View inside the drawer view to make it Closes facebook/react-native#6218 Differential Revision: D3017444 Pulled By: bestander fb-gh-sync-id: ca48a47a20a2feecae360a76f3e2c9bbe6a37700 fbshipit-source-id: ca48a47a20a2feecae360a76f3e2c9bbe6a37700
…en over the status bar Summary:The navigation drawer of most apps on android opens over the status bar, this adds an option to do so. It implements a similar API to the native DrawerLayout by adding a statusBarBackgroundColor to DrawerLayoutAndroid. Without statusBarBackgroundColor:  With statusBarBackgroundColor:  This PR depends on the changes in facebook#6195 to add the `StatusBar.HEIGHT` constant I just want to put it out there now to see if this looks good. To test without the other PR just change `StatusBar.HEIGHT` for `25`. It is implemented by making the native status bar translucent and making its background color transparent so we can draw a view of the same height as the status bar under it as a child of the DrawerLayoutAndroid. Then we can draw a semi-transparent gray View inside the drawer view to make it Closes facebook#6218 Differential Revision: D3017444 Pulled By: bestander fb-gh-sync-id: ca48a47a20a2feecae360a76f3e2c9bbe6a37700 fbshipit-source-id: ca48a47a20a2feecae360a76f3e2c9bbe6a37700
Summary: Following the PR #6195, this adds a `HEIGHT` constant on `StatusBar` for iOS. Combined with `statusBarFrameDidChange` and `statusBarFrameWillChange` StatusBar native events, it solves various problems with In-Call cellar bar / Location bar / others 40pt status bars, and offers a correct `keyboardVerticalOffset` value for the KeyboardAvoidingView component. Closes #12041 Differential Revision: D4450924 Pulled By: hramos fbshipit-source-id: 664798260f4226140f3fa3f9222a415a305d0d78
Summary: Following the PR facebook#6195, this adds a `HEIGHT` constant on `StatusBar` for iOS. Combined with `statusBarFrameDidChange` and `statusBarFrameWillChange` StatusBar native events, it solves various problems with In-Call cellar bar / Location bar / others 40pt status bars, and offers a correct `keyboardVerticalOffset` value for the KeyboardAvoidingView component. Closes facebook#12041 Differential Revision: D4450924 Pulled By: hramos fbshipit-source-id: 664798260f4226140f3fa3f9222a415a305d0d78
Summary: Following the PR facebook#6195, this adds a `HEIGHT` constant on `StatusBar` for iOS. Combined with `statusBarFrameDidChange` and `statusBarFrameWillChange` StatusBar native events, it solves various problems with In-Call cellar bar / Location bar / others 40pt status bars, and offers a correct `keyboardVerticalOffset` value for the KeyboardAvoidingView component. Closes facebook#12041 Differential Revision: D4450924 Pulled By: hramos fbshipit-source-id: 664798260f4226140f3fa3f9222a415a305d0d78
Summary: Following the PR facebook/react-native#6195, this adds a `HEIGHT` constant on `StatusBar` for iOS. Combined with `statusBarFrameDidChange` and `statusBarFrameWillChange` StatusBar native events, it solves various problems with In-Call cellar bar / Location bar / others 40pt status bars, and offers a correct `keyboardVerticalOffset` value for the KeyboardAvoidingView component. Closes facebook/react-native#12041 Differential Revision: D4450924 Pulled By: hramos fbshipit-source-id: 664798260f4226140f3fa3f9222a415a305d0d78
Summary: Following the PR facebook#6195, this adds a `HEIGHT` constant on `StatusBar` for iOS. Combined with `statusBarFrameDidChange` and `statusBarFrameWillChange` StatusBar native events, it solves various problems with In-Call cellar bar / Location bar / others 40pt status bars, and offers a correct `keyboardVerticalOffset` value for the KeyboardAvoidingView component. Closes facebook#12041 Differential Revision: D4450924 Pulled By: hramos fbshipit-source-id: 664798260f4226140f3fa3f9222a415a305d0d78
Summary: Following the PR facebook#6195, this adds a `HEIGHT` constant on `StatusBar` for iOS. Combined with `statusBarFrameDidChange` and `statusBarFrameWillChange` StatusBar native events, it solves various problems with In-Call cellar bar / Location bar / others 40pt status bars, and offers a correct `keyboardVerticalOffset` value for the KeyboardAvoidingView component. Closes facebook#12041 Differential Revision: D4450924 Pulled By: hramos fbshipit-source-id: 664798260f4226140f3fa3f9222a415a305d0d78
Summary: Following the PR facebook#6195, this adds a `HEIGHT` constant on `StatusBar` for iOS. Combined with `statusBarFrameDidChange` and `statusBarFrameWillChange` StatusBar native events, it solves various problems with In-Call cellar bar / Location bar / others 40pt status bars, and offers a correct `keyboardVerticalOffset` value for the KeyboardAvoidingView component. Closes facebook#12041 Differential Revision: D4450924 Pulled By: hramos fbshipit-source-id: 664798260f4226140f3fa3f9222a415a305d0d78
Summary: Following the PR facebook#6195, this adds a `HEIGHT` constant on `StatusBar` for iOS. Combined with `statusBarFrameDidChange` and `statusBarFrameWillChange` StatusBar native events, it solves various problems with In-Call cellar bar / Location bar / others 40pt status bars, and offers a correct `keyboardVerticalOffset` value for the KeyboardAvoidingView component. Closes facebook#12041 Differential Revision: D4450924 Pulled By: hramos fbshipit-source-id: 664798260f4226140f3fa3f9222a415a305d0d78
Summary: Following the PR facebook#6195, this adds a `HEIGHT` constant on `StatusBar` for iOS. Combined with `statusBarFrameDidChange` and `statusBarFrameWillChange` StatusBar native events, it solves various problems with In-Call cellar bar / Location bar / others 40pt status bars, and offers a correct `keyboardVerticalOffset` value for the KeyboardAvoidingView component. Closes facebook#12041 Differential Revision: D4450924 Pulled By: hramos fbshipit-source-id: 664798260f4226140f3fa3f9222a415a305d0d78
Summary: Following the PR facebook#6195, this adds a `HEIGHT` constant on `StatusBar` for iOS. Combined with `statusBarFrameDidChange` and `statusBarFrameWillChange` StatusBar native events, it solves various problems with In-Call cellar bar / Location bar / others 40pt status bars, and offers a correct `keyboardVerticalOffset` value for the KeyboardAvoidingView component. Closes facebook#12041 Differential Revision: D4450924 Pulled By: hramos fbshipit-source-id: 664798260f4226140f3fa3f9222a415a305d0d78
Summary: Following the PR facebook#6195, this adds a `HEIGHT` constant on `StatusBar` for iOS. Combined with `statusBarFrameDidChange` and `statusBarFrameWillChange` StatusBar native events, it solves various problems with In-Call cellar bar / Location bar / others 40pt status bars, and offers a correct `keyboardVerticalOffset` value for the KeyboardAvoidingView component. Closes facebook#12041 Differential Revision: D4450924 Pulled By: hramos fbshipit-source-id: 664798260f4226140f3fa3f9222a415a305d0d78
Summary: Following the PR facebook#6195, this adds a `HEIGHT` constant on `StatusBar` for iOS. Combined with `statusBarFrameDidChange` and `statusBarFrameWillChange` StatusBar native events, it solves various problems with In-Call cellar bar / Location bar / others 40pt status bars, and offers a correct `keyboardVerticalOffset` value for the KeyboardAvoidingView component. Closes facebook#12041 Differential Revision: D4450924 Pulled By: hramos fbshipit-source-id: 664798260f4226140f3fa3f9222a415a305d0d78
Summary: Following the PR facebook#6195, this adds a `HEIGHT` constant on `StatusBar` for iOS. Combined with `statusBarFrameDidChange` and `statusBarFrameWillChange` StatusBar native events, it solves various problems with In-Call cellar bar / Location bar / others 40pt status bars, and offers a correct `keyboardVerticalOffset` value for the KeyboardAvoidingView component. Closes facebook#12041 Differential Revision: D4450924 Pulled By: hramos fbshipit-source-id: 664798260f4226140f3fa3f9222a415a305d0d78
Summary: Following the PR facebook#6195, this adds a `HEIGHT` constant on `StatusBar` for iOS. Combined with `statusBarFrameDidChange` and `statusBarFrameWillChange` StatusBar native events, it solves various problems with In-Call cellar bar / Location bar / others 40pt status bars, and offers a correct `keyboardVerticalOffset` value for the KeyboardAvoidingView component. Closes facebook#12041 Differential Revision: D4450924 Pulled By: hramos fbshipit-source-id: 664798260f4226140f3fa3f9222a415a305d0d78
Summary: Following the PR facebook#6195, this adds a `HEIGHT` constant on `StatusBar` for iOS. Combined with `statusBarFrameDidChange` and `statusBarFrameWillChange` StatusBar native events, it solves various problems with In-Call cellar bar / Location bar / others 40pt status bars, and offers a correct `keyboardVerticalOffset` value for the KeyboardAvoidingView component. Closes facebook#12041 Differential Revision: D4450924 Pulled By: hramos fbshipit-source-id: 664798260f4226140f3fa3f9222a415a305d0d78
Summary: Following the PR facebook#6195, this adds a `HEIGHT` constant on `StatusBar` for iOS. Combined with `statusBarFrameDidChange` and `statusBarFrameWillChange` StatusBar native events, it solves various problems with In-Call cellar bar / Location bar / others 40pt status bars, and offers a correct `keyboardVerticalOffset` value for the KeyboardAvoidingView component. Closes facebook#12041 Differential Revision: D4450924 Pulled By: hramos fbshipit-source-id: 664798260f4226140f3fa3f9222a415a305d0d78
Summary: Following the PR facebook#6195, this adds a `HEIGHT` constant on `StatusBar` for iOS. Combined with `statusBarFrameDidChange` and `statusBarFrameWillChange` StatusBar native events, it solves various problems with In-Call cellar bar / Location bar / others 40pt status bars, and offers a correct `keyboardVerticalOffset` value for the KeyboardAvoidingView component. Closes facebook#12041 Differential Revision: D4450924 Pulled By: hramos fbshipit-source-id: 664798260f4226140f3fa3f9222a415a305d0d78
Summary: Following the PR facebook#6195, this adds a `HEIGHT` constant on `StatusBar` for iOS. Combined with `statusBarFrameDidChange` and `statusBarFrameWillChange` StatusBar native events, it solves various problems with In-Call cellar bar / Location bar / others 40pt status bars, and offers a correct `keyboardVerticalOffset` value for the KeyboardAvoidingView component. Closes facebook#12041 Differential Revision: D4450924 Pulled By: hramos fbshipit-source-id: 664798260f4226140f3fa3f9222a415a305d0d78
Summary: Following the PR facebook#6195, this adds a `HEIGHT` constant on `StatusBar` for iOS. Combined with `statusBarFrameDidChange` and `statusBarFrameWillChange` StatusBar native events, it solves various problems with In-Call cellar bar / Location bar / others 40pt status bars, and offers a correct `keyboardVerticalOffset` value for the KeyboardAvoidingView component. Closes facebook#12041 Differential Revision: D4450924 Pulled By: hramos fbshipit-source-id: 664798260f4226140f3fa3f9222a415a305d0d78
After a year, still no update on how to deal with in-call status bar height changes on iOS? That should be a fairly common use case that needs to be addressed, and right now I don't see a clear way to detect and catch status bar height change on iOS. I looked at https://github.com/jgkim/react-native-status-bar-size which hasn't been updated in a year and that relies on StatusBarIOS, which seems to be deprecated in RN now? A pointer on what's current best practice in dealing with dynamic status bar on iOS would be appreciated, if this is a NOFIX. |
Something else to consider, Android N's Multi-Window/Split-Screen mode may also change how the status bar is handled. |
This adds a
HEIGHT
constant onStatusBar
on Android. I needed only this for now but I will work on a better status bar dimensions API later (see TODO).It also improves the implementation to fix a bug that happened when multiple
StatusBar
components get updated in the same frame as well as remove useless calls to theStatusBarModule
when values did not change.Instead of calling the
StatusBarManager
immediately when the component gets updated and relying on the order of the calls that get dispatched to native we now wait at the end of the frame to send the calls to theStatusBarManager
usingsetImmediate
. To make this work properly we need to change the data structure of the props stack a little bit to store the desired transition/animation too for each value.Finally this updates the example to only show the ones that work for the current platform.
Test plan
In the UIExplorer Example, in the 'StatusBar dimensions' section it should show 25 for the height of the status bar.
All the StatusBar props should still work as they were before but the StatusBarManager should only get called once per frame and only for the values that changed.