mirror of
https://github.com/status-im/react-native.git
synced 2025-02-04 05:34:15 +00:00
Cross platform status bar API
Summary: I started working on improving the `StatusBar` API and make it work on Android. I added support for `setColor`, `setTranslucent` (the status bar is still visible but the app can draw under) and `setHidden` on Android. Looking for feedback on how to improve the API before I put more time on this :). Right now I went for a cross platform API and functions that don't exist on a platform are just a no-op but I'm not sure it is the best choice since at the moment what is supported is very different between both platforms. I was wondering what you guys think and if it would be better off as 2 different modules. It is also possible to port some of the features I added for Android to iOS even if there is no 'standard' way to do it. Like `setColor` could be implemented by drawing a colored view under the status bar and translucent by adding/removing some padding. Closes https://github.com/facebook/react-native/pull/5360 Reviewed By: svcscm Differential Revision: D2840417 Pulled By: nicklockwood fb-gh-sync-id: 5c8d988bccf8035341f0efe27e54dd8402c18d24
This commit is contained in:
parent
0c91931adf
commit
b979128c54
206
Examples/UIExplorer/StatusBarExample.js
Normal file
206
Examples/UIExplorer/StatusBarExample.js
Normal file
@ -0,0 +1,206 @@
|
||||
/**
|
||||
* The examples provided by Facebook are for non-commercial testing and
|
||||
* evaluation purposes only.
|
||||
*
|
||||
* Facebook reserves all rights not expressly granted.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL
|
||||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
||||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const React = require('react-native');
|
||||
const {
|
||||
StyleSheet,
|
||||
View,
|
||||
Text,
|
||||
TouchableHighlight,
|
||||
StatusBar,
|
||||
} = React;
|
||||
|
||||
type BarStyle = 'default' | 'light-content';
|
||||
type ShowHideTransition = 'fade' | 'slide';
|
||||
|
||||
type State = {
|
||||
animated: boolean,
|
||||
backgroundColor: string,
|
||||
hidden?: boolean,
|
||||
showHideTransition: ShowHideTransition,
|
||||
translucent?: boolean,
|
||||
barStyle?: BarStyle,
|
||||
networkActivityIndicatorVisible?: boolean
|
||||
};
|
||||
|
||||
exports.framework = 'React';
|
||||
exports.title = '<StatusBar>';
|
||||
exports.description = 'Component for controlling the status bar';
|
||||
|
||||
const colors = [
|
||||
'#ff0000',
|
||||
'#00ff00',
|
||||
'#0000ff',
|
||||
];
|
||||
|
||||
const barStyles = [
|
||||
'default',
|
||||
'light-content',
|
||||
];
|
||||
|
||||
const showHideTransitions = [
|
||||
'fade',
|
||||
'slide',
|
||||
];
|
||||
|
||||
const StatusBarExample = React.createClass({
|
||||
getInitialState(): State {
|
||||
return {
|
||||
animated: true,
|
||||
backgroundColor: this._getValue(colors, 0),
|
||||
showHideTransition: this._getValue(showHideTransitions, 0),
|
||||
};
|
||||
},
|
||||
|
||||
_colorIndex: 0,
|
||||
_barStyleIndex: 0,
|
||||
_showHideTransitionIndex: 0,
|
||||
|
||||
_getValue(values: Array<any>, index: number): any {
|
||||
return values[index % values.length];
|
||||
},
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View>
|
||||
<StatusBar
|
||||
backgroundColor={this.state.backgroundColor}
|
||||
translucent={this.state.translucent}
|
||||
hidden={this.state.hidden}
|
||||
showHideTransition={this.state.showHideTransition}
|
||||
animated={this.state.animated}
|
||||
barStyle={this.state.barStyle}
|
||||
networkActivityIndicatorVisible={this.state.networkActivityIndicatorVisible}
|
||||
/>
|
||||
<View>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => this.setState({animated: !this.state.animated})}>
|
||||
<View style={styles.button}>
|
||||
<Text>animated: {this.state.animated ? 'true' : 'false'}</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
</View>
|
||||
<View>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => this.setState({hidden: !this.state.hidden})}>
|
||||
<View style={styles.button}>
|
||||
<Text>hidden: {this.state.hidden ? 'true' : 'false'}</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
</View>
|
||||
<Text style={styles.title}>iOS</Text>
|
||||
<View>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => {
|
||||
this._barStyleIndex++;
|
||||
this.setState({barStyle: this._getValue(barStyles, this._barStyleIndex)});
|
||||
}}>
|
||||
<View style={styles.button}>
|
||||
<Text>style: '{this._getValue(barStyles, this._barStyleIndex)}'</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
</View>
|
||||
<View>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => this.setState({
|
||||
networkActivityIndicatorVisible: !this.state.networkActivityIndicatorVisible,
|
||||
})}>
|
||||
<View style={styles.button}>
|
||||
<Text>
|
||||
networkActivityIndicatorVisible:
|
||||
{this.state.networkActivityIndicatorVisible ? 'true' : 'false'}
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
</View>
|
||||
<View>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => {
|
||||
this._showHideTransitionIndex++;
|
||||
this.setState({
|
||||
showHideTransition:
|
||||
this._getValue(showHideTransitions, this._showHideTransitionIndex),
|
||||
});
|
||||
}}>
|
||||
<View style={styles.button}>
|
||||
<Text>
|
||||
showHideTransition:
|
||||
'{this._getValue(showHideTransitions, this._showHideTransitionIndex)}'
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
</View>
|
||||
<Text style={styles.title}>Android</Text>
|
||||
<View>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => {
|
||||
this._colorIndex++;
|
||||
this.setState({backgroundColor: this._getValue(colors, this._colorIndex)});
|
||||
}}>
|
||||
<View style={styles.button}>
|
||||
<Text>backgroundColor: '{this._getValue(colors, this._colorIndex)}'</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
</View>
|
||||
<View>
|
||||
<TouchableHighlight
|
||||
style={styles.wrapper}
|
||||
onPress={() => {
|
||||
this.setState({
|
||||
translucent: !this.state.translucent,
|
||||
backgroundColor: !this.state.translucent ? 'rgba(0, 0, 0, 0.4)' : 'black',
|
||||
});
|
||||
}}>
|
||||
<View style={styles.button}>
|
||||
<Text>translucent: {this.state.translucent ? 'true' : 'false'}</Text>
|
||||
</View>
|
||||
</TouchableHighlight>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
exports.examples = [{
|
||||
title: 'Status Bar',
|
||||
render() {
|
||||
return <StatusBarExample />;
|
||||
},
|
||||
}];
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
wrapper: {
|
||||
borderRadius: 5,
|
||||
marginBottom: 5,
|
||||
},
|
||||
button: {
|
||||
borderRadius: 5,
|
||||
backgroundColor: '#eeeeee',
|
||||
padding: 10,
|
||||
},
|
||||
title: {
|
||||
marginTop: 16,
|
||||
marginBottom: 8,
|
||||
fontWeight: 'bold',
|
||||
}
|
||||
});
|
@ -25,6 +25,7 @@ var {
|
||||
StyleSheet,
|
||||
ToolbarAndroid,
|
||||
View,
|
||||
StatusBar,
|
||||
} = React;
|
||||
var UIExplorerList = require('./UIExplorerList.android');
|
||||
|
||||
@ -98,6 +99,9 @@ var UIExplorerApp = React.createClass({
|
||||
var Component = this.state.example.component;
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<StatusBar
|
||||
backgroundColor="#589c90"
|
||||
/>
|
||||
<ToolbarAndroid
|
||||
logo={require('image!launcher_icon')}
|
||||
navIcon={require('image!ic_menu_black_24dp')}
|
||||
|
@ -24,7 +24,8 @@ var {
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableHighlight,
|
||||
View
|
||||
View,
|
||||
StatusBar,
|
||||
} = React;
|
||||
|
||||
var UIExplorerApp = React.createClass({
|
||||
@ -48,20 +49,23 @@ var UIExplorerApp = React.createClass({
|
||||
}
|
||||
|
||||
return (
|
||||
<NavigatorIOS
|
||||
style={styles.container}
|
||||
initialRoute={{
|
||||
title: 'UIExplorer',
|
||||
component: UIExplorerList,
|
||||
passProps: {
|
||||
onExternalExampleRequested: (example) => {
|
||||
this.setState({ openExternalExample: example, });
|
||||
},
|
||||
}
|
||||
}}
|
||||
itemWrapperStyle={styles.itemWrapper}
|
||||
tintColor="#008888"
|
||||
/>
|
||||
<View style={{flex: 1}}>
|
||||
<StatusBar barStyle="default" />
|
||||
<NavigatorIOS
|
||||
style={styles.container}
|
||||
initialRoute={{
|
||||
title: 'UIExplorer',
|
||||
component: UIExplorerList,
|
||||
passProps: {
|
||||
onExternalExampleRequested: (example) => {
|
||||
this.setState({ openExternalExample: example, });
|
||||
},
|
||||
}
|
||||
}}
|
||||
itemWrapperStyle={styles.itemWrapper}
|
||||
tintColor="#008888"
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
@ -30,6 +30,7 @@ var COMPONENTS = [
|
||||
require('./PullToRefreshViewAndroidExample.android'),
|
||||
require('./RefreshControlExample'),
|
||||
require('./ScrollViewSimpleExample'),
|
||||
require('./StatusBarExample'),
|
||||
require('./SwitchExample'),
|
||||
require('./TextExample.android'),
|
||||
require('./TextInputExample.android'),
|
||||
|
@ -46,6 +46,7 @@ var COMPONENTS = [
|
||||
require('./ScrollViewExample'),
|
||||
require('./SegmentedControlIOSExample'),
|
||||
require('./SliderIOSExample'),
|
||||
require('./StatusBarExample'),
|
||||
require('./SwitchExample'),
|
||||
require('./TabBarIOSExample'),
|
||||
require('./TextExample.ios'),
|
||||
|
194
Libraries/Components/StatusBar/StatusBar.js
Normal file
194
Libraries/Components/StatusBar/StatusBar.js
Normal file
@ -0,0 +1,194 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
* @providesModule StatusBar
|
||||
* @flow
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
const React = require('React');
|
||||
const ColorPropType = require('ColorPropType');
|
||||
const Platform = require('Platform');
|
||||
|
||||
const processColor = require('processColor');
|
||||
|
||||
const StatusBarManager = require('NativeModules').StatusBarManager;
|
||||
|
||||
type DefaultProps = {
|
||||
animated: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* Merges the prop stack with the default values.
|
||||
*/
|
||||
function mergePropsStack(propsStack: Array<Object>): Object {
|
||||
return propsStack.reduce((prev, cur) => {
|
||||
return Object.assign(prev, cur);
|
||||
}, {
|
||||
backgroundColor: 'black',
|
||||
barStyle: 'default',
|
||||
translucent: false,
|
||||
hidden: false,
|
||||
networkActivityIndicatorVisible: false,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Component to control the app status bar.
|
||||
*
|
||||
* ### Usage with Navigator
|
||||
*
|
||||
* It is possible to have multiple `StatusBar` components mounted at the same
|
||||
* time. The props will be merged in the order the `StatusBar` components were
|
||||
* mounted. One use case is to specify status bar styles per route using `Navigator`.
|
||||
*
|
||||
* ```
|
||||
* <View>
|
||||
* <StatusBar
|
||||
* backgroundColor="blue"
|
||||
* barStyle="light-content"
|
||||
* />
|
||||
* <Navigator
|
||||
* initialRoute={{statusBarHidden: true}}
|
||||
* renderScene={(route, navigator) =>
|
||||
* <View>
|
||||
* <StatusBar hidden={route.statusBarHidden} />
|
||||
* ...
|
||||
* </View>
|
||||
* }
|
||||
* />
|
||||
* </View>
|
||||
* ```
|
||||
*/
|
||||
const StatusBar = React.createClass({
|
||||
statics: {
|
||||
_propsStack: [],
|
||||
},
|
||||
|
||||
propTypes: {
|
||||
/**
|
||||
* If the status bar is hidden.
|
||||
*/
|
||||
hidden: React.PropTypes.bool,
|
||||
/**
|
||||
* If the transition between status bar property changes should be animated.
|
||||
* Supported for backgroundColor, barStyle and hidden.
|
||||
*/
|
||||
animated: React.PropTypes.bool,
|
||||
/**
|
||||
* The background color of the status bar.
|
||||
* @platform android
|
||||
*/
|
||||
backgroundColor: ColorPropType,
|
||||
/**
|
||||
* If the status bar is translucent.
|
||||
* When translucent is set to true, the app will draw under the status bar.
|
||||
* This is useful when using a semi transparent status bar color.
|
||||
*
|
||||
* @platform android
|
||||
*/
|
||||
translucent: React.PropTypes.bool,
|
||||
/**
|
||||
* Sets the color of the status bar text.
|
||||
*
|
||||
* @platform ios
|
||||
*/
|
||||
barStyle: React.PropTypes.oneOf([
|
||||
'default',
|
||||
'light-content',
|
||||
]),
|
||||
/**
|
||||
* If the network activity indicator should be visible.
|
||||
*
|
||||
* @platform ios
|
||||
*/
|
||||
networkActivityIndicatorVisible: React.PropTypes.bool,
|
||||
/**
|
||||
* The transition effect when showing and hiding the status bar using the `hidden`
|
||||
* prop. Defaults to 'fade'.
|
||||
*
|
||||
* @platform ios
|
||||
*/
|
||||
showHideTransition: React.PropTypes.oneOf([
|
||||
'fade',
|
||||
'slide',
|
||||
]),
|
||||
},
|
||||
|
||||
getDefaultProps(): DefaultProps {
|
||||
return {
|
||||
animated: false,
|
||||
showHideTransition: 'fade',
|
||||
};
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
// Every time a StatusBar component is mounted, we push it's prop to a stack
|
||||
// and always update the native status bar with the props from the top of then
|
||||
// stack. This allows having multiple StatusBar components and the one that is
|
||||
// added last or is deeper in the view hierachy will have priority.
|
||||
StatusBar._propsStack.push(this.props);
|
||||
this._updatePropsStack();
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
// When a StatusBar is unmounted, remove itself from the stack and update
|
||||
// the native bar with the next props.
|
||||
const index = StatusBar._propsStack.indexOf(this.props);
|
||||
StatusBar._propsStack.splice(index, 1);
|
||||
|
||||
this._updatePropsStack();
|
||||
},
|
||||
|
||||
componentDidUpdate(oldProps: Object) {
|
||||
const index = StatusBar._propsStack.indexOf(oldProps);
|
||||
StatusBar._propsStack[index] = this.props;
|
||||
|
||||
this._updatePropsStack();
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the native status bar with the props from the stack.
|
||||
*/
|
||||
_updatePropsStack() {
|
||||
const mergedProps = mergePropsStack(StatusBar._propsStack);
|
||||
|
||||
if (Platform.OS === 'ios') {
|
||||
if (mergedProps.barStyle !== undefined) {
|
||||
StatusBarManager.setStyle(mergedProps.barStyle, this.props.animated);
|
||||
}
|
||||
if (mergedProps.hidden !== undefined) {
|
||||
StatusBarManager.setHidden(
|
||||
mergedProps.hidden,
|
||||
this.props.animated ? this.props.showHideTransition : 'none'
|
||||
);
|
||||
}
|
||||
if (mergedProps.networkActivityIndicatorVisible !== undefined) {
|
||||
StatusBarManager.setNetworkActivityIndicatorVisible(
|
||||
mergedProps.networkActivityIndicatorVisible
|
||||
);
|
||||
}
|
||||
} else if (Platform.OS === 'android') {
|
||||
if (mergedProps.backgroundColor !== undefined) {
|
||||
StatusBarManager.setColor(processColor(mergedProps.backgroundColor), this.props.animated);
|
||||
}
|
||||
if (mergedProps.hidden !== undefined) {
|
||||
StatusBarManager.setHidden(mergedProps.hidden);
|
||||
}
|
||||
if (mergedProps.translucent !== undefined) {
|
||||
StatusBarManager.setTranslucent(mergedProps.translucent);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
render(): ?ReactElement {
|
||||
return null;
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = StatusBar;
|
1
Libraries/react-native/react-native.js
vendored
1
Libraries/react-native/react-native.js
vendored
@ -37,6 +37,7 @@ var ReactNative = {
|
||||
get PullToRefreshViewAndroid() { return require('PullToRefreshViewAndroid'); },
|
||||
get RecyclerViewBackedScrollView() { return require('RecyclerViewBackedScrollView'); },
|
||||
get RefreshControl() { return require('RefreshControl'); },
|
||||
get StatusBar() { return require('StatusBar'); },
|
||||
get SwitchAndroid() { return require('SwitchAndroid'); },
|
||||
get SwitchIOS() { return require('SwitchIOS'); },
|
||||
get TabBarIOS() { return require('TabBarIOS'); },
|
||||
|
@ -45,6 +45,7 @@ var ReactNative = Object.assign(Object.create(require('React')), {
|
||||
SegmentedControlIOS: require('SegmentedControlIOS'),
|
||||
SliderIOS: require('SliderIOS'),
|
||||
SnapshotViewIOS: require('SnapshotViewIOS'),
|
||||
StatusBar: require('StatusBar'),
|
||||
Switch: require('Switch'),
|
||||
PullToRefreshViewAndroid: require('PullToRefreshViewAndroid'),
|
||||
RecyclerViewBackedScrollView: require('RecyclerViewBackedScrollView'),
|
||||
|
@ -9,6 +9,8 @@
|
||||
|
||||
package com.facebook.react.bridge;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Interface that represents a JavaScript Promise which can be passed to the native module as a
|
||||
* method parameter.
|
||||
@ -21,7 +23,7 @@ public interface Promise {
|
||||
/**
|
||||
* Successfully resolve the Promise.
|
||||
*/
|
||||
void resolve(Object value);
|
||||
void resolve(@Nullable Object value);
|
||||
|
||||
/**
|
||||
* Report an error which wasn't caused by an exception.
|
||||
|
@ -0,0 +1,20 @@
|
||||
include_defs('//ReactAndroid/DEFS')
|
||||
|
||||
android_library(
|
||||
name = 'statusbar',
|
||||
srcs = glob(['**/*.java']),
|
||||
deps = [
|
||||
react_native_target('java/com/facebook/react/bridge:bridge'),
|
||||
react_native_target('java/com/facebook/react/common:common'),
|
||||
react_native_dep('third-party/android/support/v4:lib-support-v4'),
|
||||
react_native_dep('third-party/java/infer-annotations:infer-annotations'),
|
||||
react_native_dep('third-party/java/jsr-305:jsr-305'),
|
||||
],
|
||||
visibility = [
|
||||
'PUBLIC',
|
||||
],
|
||||
)
|
||||
|
||||
project_config(
|
||||
src_target = ':statusbar',
|
||||
)
|
@ -0,0 +1,132 @@
|
||||
/**
|
||||
* Copyright (c) 2015-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
* <p/>
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
|
||||
|
||||
package com.facebook.react.modules.statusbar;
|
||||
|
||||
import android.animation.ArgbEvaluator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.os.Build;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.view.View;
|
||||
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.bridge.UiThreadUtil;
|
||||
|
||||
public class StatusBarModule extends ReactContextBaseJavaModule {
|
||||
|
||||
private static final String ERROR_NO_ACTIVITY =
|
||||
"Tried to change the status bar while not attached to an Activity";
|
||||
|
||||
private int mWindowFlags = 0;
|
||||
|
||||
public StatusBarModule(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "StatusBarManager";
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void setColor(final int color, final boolean animated, final Promise res) {
|
||||
final Activity activity = getCurrentActivity();
|
||||
if (activity == null) {
|
||||
res.reject(ERROR_NO_ACTIVITY);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
UiThreadUtil.runOnUiThread(
|
||||
new Runnable() {
|
||||
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||
@Override
|
||||
public void run() {
|
||||
if (animated) {
|
||||
int curColor = activity.getWindow().getStatusBarColor();
|
||||
ValueAnimator colorAnimation = ValueAnimator.ofObject(
|
||||
new ArgbEvaluator(), curColor, color);
|
||||
|
||||
colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
|
||||
@Override
|
||||
public void onAnimationUpdate(ValueAnimator animator) {
|
||||
activity.getWindow().setStatusBarColor((Integer) animator.getAnimatedValue());
|
||||
}
|
||||
});
|
||||
colorAnimation
|
||||
.setDuration(300)
|
||||
.setStartDelay(0);
|
||||
colorAnimation.start();
|
||||
} else {
|
||||
activity.getWindow().setStatusBarColor(color);
|
||||
}
|
||||
res.resolve(null);
|
||||
}
|
||||
}
|
||||
);
|
||||
} else {
|
||||
res.resolve(null);
|
||||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void setTranslucent(final boolean translucent, final Promise res) {
|
||||
final Activity activity = getCurrentActivity();
|
||||
if (activity == null) {
|
||||
res.reject(ERROR_NO_ACTIVITY);
|
||||
return;
|
||||
}
|
||||
UiThreadUtil.runOnUiThread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (translucent) {
|
||||
mWindowFlags |=
|
||||
View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
|
||||
} else {
|
||||
mWindowFlags &=
|
||||
~(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
|
||||
}
|
||||
activity.getWindow().getDecorView().setSystemUiVisibility(mWindowFlags);
|
||||
ViewCompat.requestApplyInsets(activity.getWindow().getDecorView());
|
||||
res.resolve(null);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void setHidden(final boolean hidden, final Promise res) {
|
||||
final Activity activity = getCurrentActivity();
|
||||
if (activity == null) {
|
||||
res.reject(ERROR_NO_ACTIVITY);
|
||||
return;
|
||||
}
|
||||
UiThreadUtil.runOnUiThread(
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (hidden) {
|
||||
mWindowFlags |= View.SYSTEM_UI_FLAG_FULLSCREEN;
|
||||
} else {
|
||||
mWindowFlags &= ~View.SYSTEM_UI_FLAG_FULLSCREEN;
|
||||
}
|
||||
activity.getWindow().getDecorView().setSystemUiVisibility(mWindowFlags);
|
||||
res.resolve(null);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
@ -36,6 +36,7 @@ android_library(
|
||||
react_native_target('java/com/facebook/react/modules/location:location'),
|
||||
react_native_target('java/com/facebook/react/modules/netinfo:netinfo'),
|
||||
react_native_target('java/com/facebook/react/modules/network:network'),
|
||||
react_native_target('java/com/facebook/react/modules/statusbar:statusbar'),
|
||||
react_native_target('java/com/facebook/react/modules/storage:storage'),
|
||||
react_native_target('java/com/facebook/react/modules/timepicker:timepicker'),
|
||||
react_native_target('java/com/facebook/react/modules/toast:toast'),
|
||||
|
@ -29,6 +29,7 @@ import com.facebook.react.modules.intent.IntentModule;
|
||||
import com.facebook.react.modules.location.LocationModule;
|
||||
import com.facebook.react.modules.netinfo.NetInfoModule;
|
||||
import com.facebook.react.modules.network.NetworkingModule;
|
||||
import com.facebook.react.modules.statusbar.StatusBarModule;
|
||||
import com.facebook.react.modules.storage.AsyncStorageModule;
|
||||
import com.facebook.react.modules.timepicker.TimePickerDialogModule;
|
||||
import com.facebook.react.modules.toast.ToastModule;
|
||||
@ -77,9 +78,11 @@ public class MainReactPackage implements ReactPackage {
|
||||
new LocationModule(reactContext),
|
||||
new NetworkingModule(reactContext),
|
||||
new NetInfoModule(reactContext),
|
||||
new StatusBarModule(reactContext),
|
||||
new TimePickerDialogModule(reactContext),
|
||||
new ToastModule(reactContext),
|
||||
new WebSocketModule(reactContext));
|
||||
new WebSocketModule(reactContext)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -208,6 +208,7 @@ var components = [
|
||||
'../Libraries/Components/ScrollView/ScrollView.js',
|
||||
'../Libraries/Components/SegmentedControlIOS/SegmentedControlIOS.ios.js',
|
||||
'../Libraries/Components/SliderIOS/SliderIOS.ios.js',
|
||||
'../Libraries/Components/StatusBar/StatusBar.js',
|
||||
'../Libraries/Components/Switch/Switch.js',
|
||||
'../Libraries/Components/TabBarIOS/TabBarIOS.ios.js',
|
||||
'../Libraries/Components/TabBarIOS/TabBarItemIOS.ios.js',
|
||||
|
Loading…
x
Reference in New Issue
Block a user