From c4ac8b329c242e1217f311d374354446a664eaea Mon Sep 17 00:00:00 2001 From: Alexander Pantyuhov Date: Fri, 30 Sep 2016 12:49:05 -0700 Subject: [PATCH] StatusBar: barStyle support for Android (API 23+) Summary: Android (starting from API 23) supports "light status bar", thus it is possible to extend StatusBar and make `barStyle` property work not only for iOS, but also for Android. This PR introduces one more `barStyle` option `dark-content` in addition to two existing ones (`default` and `light-content`). Why there are 3 options instead of 2? Two simple reasons: 1) to make all existing applications fully compatible with these changes; 2) the default status bar on Android is dark with white text and icons, while on iOS it is light with black text and icons on it. Thus the `default` option means something like "I don't really care, just apply the default color for this platform", while two other options (`light-content` and `dark-content`) allow to accurately specify the required result. Closes https://github.com/facebook/react-native/pull/10185 Differential Revision: D3952346 fbshipit-source-id: 999a67614abff52321fbeb06298ebf1946c3f1d1 --- Libraries/Components/StatusBar/StatusBar.js | 24 ++++++++++++------- React/Modules/RCTStatusBarManager.m | 1 + .../modules/statusbar/StatusBarModule.java | 24 +++++++++++++++++++ 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/Libraries/Components/StatusBar/StatusBar.js b/Libraries/Components/StatusBar/StatusBar.js index 6df5d4ca2..f30bd2b44 100644 --- a/Libraries/Components/StatusBar/StatusBar.js +++ b/Libraries/Components/StatusBar/StatusBar.js @@ -24,13 +24,17 @@ const StatusBarManager = require('NativeModules').StatusBarManager; */ export type StatusBarStyle = $Enum<{ /** - * Default status bar style + * Default status bar style (dark for iOS, light for Android) */ 'default': string, /** - * Dark background style + * Dark background, white texts and icons */ 'light-content': string, + /** + * Light background, dark texts and icons + */ + 'dark-content': string, }>; /** @@ -134,7 +138,7 @@ class StatusBar extends React.Component { animated?: boolean, backgroundColor?: $FlowFixMe, translucent?: boolean, - barStyle?: 'default' | 'light-content', + barStyle?: 'default' | 'light-content' | 'dark-content', networkActivityIndicatorVisible?: boolean, showHideTransition?: 'fade' | 'slide', }; @@ -191,13 +195,13 @@ class StatusBar extends React.Component { * @param animated Animate the style change. */ static setBarStyle(style: StatusBarStyle, animated?: boolean) { - if (Platform.OS !== 'ios') { - console.warn('`setBarStyle` is only available on iOS'); - return; - } animated = animated || false; StatusBar._defaultProps.barStyle.value = style; - StatusBarManager.setStyle(style, animated); + if (Platform.OS === 'ios') { + StatusBarManager.setStyle(style, animated); + } else if (Platform.OS === 'android') { + StatusBarManager.setStyle(style); + } } /** @@ -272,6 +276,7 @@ class StatusBar extends React.Component { barStyle: React.PropTypes.oneOf([ 'default', 'light-content', + 'dark-content', ]), /** * If the network activity indicator should be visible. @@ -360,6 +365,9 @@ class StatusBar extends React.Component { ); } } else if (Platform.OS === 'android') { + if (!oldProps || oldProps.barStyle.value !== mergedProps.barStyle.value) { + StatusBarManager.setStyle(mergedProps.barStyle.value); + } if (!oldProps || oldProps.backgroundColor.value !== mergedProps.backgroundColor.value) { StatusBarManager.setColor( processColor(mergedProps.backgroundColor.value), diff --git a/React/Modules/RCTStatusBarManager.m b/React/Modules/RCTStatusBarManager.m index 9036469a4..bc47eda13 100644 --- a/React/Modules/RCTStatusBarManager.m +++ b/React/Modules/RCTStatusBarManager.m @@ -18,6 +18,7 @@ RCT_ENUM_CONVERTER(UIStatusBarStyle, (@{ @"default": @(UIStatusBarStyleDefault), @"light-content": @(UIStatusBarStyleLightContent), + @"dark-content": @(UIStatusBarStyleDefault), }), UIStatusBarStyleDefault, integerValue); RCT_ENUM_CONVERTER(UIStatusBarAnimation, (@{ diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/statusbar/StatusBarModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/statusbar/StatusBarModule.java index 931a7821c..c58219cdc 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/statusbar/StatusBarModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/statusbar/StatusBarModule.java @@ -170,4 +170,28 @@ public class StatusBarModule extends ReactContextBaseJavaModule { } }); } + + @ReactMethod + public void setStyle(final String style, final Promise res) { + final Activity activity = getCurrentActivity(); + if (activity == null) { + res.reject(ERROR_NO_ACTIVITY, ERROR_NO_ACTIVITY_MESSAGE); + return; + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + UiThreadUtil.runOnUiThread( + new Runnable() { + @TargetApi(Build.VERSION_CODES.M) + @Override + public void run() { + View decorView = activity.getWindow().getDecorView(); + decorView.setSystemUiVisibility( + style.equals("dark-content") ? View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR : 0); + res.resolve(null); + } + } + ); + } + } }