Add statusBarBackgroundColor to DrawerLayoutAndroid to allow it to open 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: ![image](https://cloud.githubusercontent.com/assets/2677334/13414490/50ebcdf4-df21-11e5-974f-c6a1343c2a4e.png) With statusBarBackgroundColor: ![image](https://cloud.githubusercontent.com/assets/2677334/13414459/1fdc4086-df21-11e5-9658-bd47bfdb925f.png) 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 https://github.com/facebook/react-native/pull/6218 Differential Revision: D3017444 Pulled By: bestander fb-gh-sync-id: ca48a47a20a2feecae360a76f3e2c9bbe6a37700 fbshipit-source-id: ca48a47a20a2feecae360a76f3e2c9bbe6a37700
This commit is contained in:
parent
5bbf88be5a
commit
039924ec70
|
@ -71,7 +71,8 @@ class UIExplorerApp extends React.Component {
|
||||||
this._overrideBackPressForDrawerLayout = false;
|
this._overrideBackPressForDrawerLayout = false;
|
||||||
}}
|
}}
|
||||||
ref={(drawer) => { this.drawer = drawer; }}
|
ref={(drawer) => { this.drawer = drawer; }}
|
||||||
renderNavigationView={this._renderDrawerContent.bind(this, onNavigate)}>
|
renderNavigationView={this._renderDrawerContent.bind(this, onNavigate)}
|
||||||
|
statusBarBackgroundColor="#589c90">
|
||||||
{this._renderNavigation(navigationState, onNavigate)}
|
{this._renderNavigation(navigationState, onNavigate)}
|
||||||
</DrawerLayoutAndroid>
|
</DrawerLayoutAndroid>
|
||||||
);
|
);
|
||||||
|
@ -79,6 +80,7 @@ class UIExplorerApp extends React.Component {
|
||||||
|
|
||||||
_renderDrawerContent(onNavigate) {
|
_renderDrawerContent(onNavigate) {
|
||||||
return (
|
return (
|
||||||
|
<View style={styles.drawerContentWrapper}>
|
||||||
<UIExplorerExampleList
|
<UIExplorerExampleList
|
||||||
list={UIExplorerList}
|
list={UIExplorerList}
|
||||||
displayTitleRow={true}
|
displayTitleRow={true}
|
||||||
|
@ -88,6 +90,7 @@ class UIExplorerApp extends React.Component {
|
||||||
onNavigate(action);
|
onNavigate(action);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,9 +116,6 @@ class UIExplorerApp extends React.Component {
|
||||||
const ExampleComponent = UIExplorerExampleList.makeRenderable(ExampleModule);
|
const ExampleComponent = UIExplorerExampleList.makeRenderable(ExampleModule);
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<StatusBar
|
|
||||||
backgroundColor="#589c90"
|
|
||||||
/>
|
|
||||||
<ToolbarAndroid
|
<ToolbarAndroid
|
||||||
logo={require('image!launcher_icon')}
|
logo={require('image!launcher_icon')}
|
||||||
navIcon={require('image!ic_menu_black_24dp')}
|
navIcon={require('image!ic_menu_black_24dp')}
|
||||||
|
@ -131,9 +131,6 @@ class UIExplorerApp extends React.Component {
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<StatusBar
|
|
||||||
backgroundColor="#589c90"
|
|
||||||
/>
|
|
||||||
<ToolbarAndroid
|
<ToolbarAndroid
|
||||||
logo={require('image!launcher_icon')}
|
logo={require('image!launcher_icon')}
|
||||||
navIcon={require('image!ic_menu_black_24dp')}
|
navIcon={require('image!ic_menu_black_24dp')}
|
||||||
|
@ -181,6 +178,10 @@ const styles = StyleSheet.create({
|
||||||
backgroundColor: '#E9EAED',
|
backgroundColor: '#E9EAED',
|
||||||
height: 56,
|
height: 56,
|
||||||
},
|
},
|
||||||
|
drawerContentWrapper: {
|
||||||
|
paddingTop: StatusBar.currentHeight,
|
||||||
|
backgroundColor: 'white',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
AppRegistry.registerComponent('UIExplorerApp', () => UIExplorerApp);
|
AppRegistry.registerComponent('UIExplorerApp', () => UIExplorerApp);
|
||||||
|
|
|
@ -10,9 +10,12 @@
|
||||||
*/
|
*/
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
var ColorPropType = require('ColorPropType');
|
||||||
var NativeMethodsMixin = require('NativeMethodsMixin');
|
var NativeMethodsMixin = require('NativeMethodsMixin');
|
||||||
|
var Platform = require('Platform');
|
||||||
var React = require('React');
|
var React = require('React');
|
||||||
var ReactPropTypes = require('ReactPropTypes');
|
var ReactPropTypes = require('ReactPropTypes');
|
||||||
|
var StatusBar = require('StatusBar');
|
||||||
var StyleSheet = require('StyleSheet');
|
var StyleSheet = require('StyleSheet');
|
||||||
var UIManager = require('UIManager');
|
var UIManager = require('UIManager');
|
||||||
var View = require('View');
|
var View = require('View');
|
||||||
|
@ -25,12 +28,6 @@ var requireNativeComponent = require('requireNativeComponent');
|
||||||
var RK_DRAWER_REF = 'drawerlayout';
|
var RK_DRAWER_REF = 'drawerlayout';
|
||||||
var INNERVIEW_REF = 'innerView';
|
var INNERVIEW_REF = 'innerView';
|
||||||
|
|
||||||
var DrawerLayoutValidAttributes = {
|
|
||||||
drawerWidth: true,
|
|
||||||
drawerPosition: true,
|
|
||||||
drawerLockMode: true
|
|
||||||
};
|
|
||||||
|
|
||||||
var DRAWER_STATES = [
|
var DRAWER_STATES = [
|
||||||
'Idle',
|
'Idle',
|
||||||
'Dragging',
|
'Dragging',
|
||||||
|
@ -132,21 +129,52 @@ var DrawerLayoutAndroid = React.createClass({
|
||||||
* The navigation view that will be rendered to the side of the screen and can be pulled in.
|
* The navigation view that will be rendered to the side of the screen and can be pulled in.
|
||||||
*/
|
*/
|
||||||
renderNavigationView: ReactPropTypes.func.isRequired,
|
renderNavigationView: ReactPropTypes.func.isRequired,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make the drawer take the entire screen and draw the background of the
|
||||||
|
* status bar to allow it to open over the status bar. It will only have an
|
||||||
|
* effect on API 21+.
|
||||||
|
*/
|
||||||
|
statusBarBackgroundColor: ColorPropType,
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [NativeMethodsMixin],
|
mixins: [NativeMethodsMixin],
|
||||||
|
|
||||||
|
getInitialState: function() {
|
||||||
|
return {statusBarBackgroundColor: undefined};
|
||||||
|
},
|
||||||
|
|
||||||
getInnerViewNode: function() {
|
getInnerViewNode: function() {
|
||||||
return this.refs[INNERVIEW_REF].getInnerViewNode();
|
return this.refs[INNERVIEW_REF].getInnerViewNode();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
componentDidMount: function() {
|
||||||
|
this._updateStatusBarBackground();
|
||||||
|
},
|
||||||
|
|
||||||
|
componentDidReceiveProps: function() {
|
||||||
|
this._updateStatusBarBackground();
|
||||||
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
|
var drawStatusBar = Platform.Version >= 21 && this.props.statusBarBackgroundColor;
|
||||||
var drawerViewWrapper =
|
var drawerViewWrapper =
|
||||||
<View style={[styles.drawerSubview, {width: this.props.drawerWidth}]} collapsable={false}>
|
<View style={[styles.drawerSubview, {width: this.props.drawerWidth}]} collapsable={false}>
|
||||||
{this.props.renderNavigationView()}
|
{this.props.renderNavigationView()}
|
||||||
|
{drawStatusBar && <View style={styles.drawerStatusBar} />}
|
||||||
</View>;
|
</View>;
|
||||||
var childrenWrapper =
|
var childrenWrapper =
|
||||||
<View ref={INNERVIEW_REF} style={styles.mainSubview} collapsable={false}>
|
<View ref={INNERVIEW_REF} style={styles.mainSubview} collapsable={false}>
|
||||||
|
{drawStatusBar &&
|
||||||
|
<StatusBar
|
||||||
|
translucent
|
||||||
|
backgroundColor={this.state.statusBarBackgroundColor}
|
||||||
|
/>}
|
||||||
|
{drawStatusBar &&
|
||||||
|
<View style={[
|
||||||
|
styles.statusBar,
|
||||||
|
{backgroundColor: this.props.statusBarBackgroundColor}
|
||||||
|
]} />}
|
||||||
{this.props.children}
|
{this.props.children}
|
||||||
</View>;
|
</View>;
|
||||||
return (
|
return (
|
||||||
|
@ -213,6 +241,23 @@ var DrawerLayoutAndroid = React.createClass({
|
||||||
_getDrawerLayoutHandle: function() {
|
_getDrawerLayoutHandle: function() {
|
||||||
return React.findNodeHandle(this.refs[RK_DRAWER_REF]);
|
return React.findNodeHandle(this.refs[RK_DRAWER_REF]);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Update the StatusBar component background color one frame after creating the
|
||||||
|
// status bar background View to avoid a white flicker that happens because
|
||||||
|
// the StatusBar background becomes transparent before the status bar View
|
||||||
|
// from this component has rendered.
|
||||||
|
_updateStatusBarBackground: function() {
|
||||||
|
if (Platform.Version >= 21 && this.props.statusBarBackgroundColor) {
|
||||||
|
// Check if the value is not already transparent to avoid an extra render.
|
||||||
|
if (this.state.statusBarBackgroundColor !== 'transparent') {
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
this.setState({statusBarBackgroundColor: 'transparent'});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.setState({statusBarBackgroundColor: undefined});
|
||||||
|
}
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
var styles = StyleSheet.create({
|
var styles = StyleSheet.create({
|
||||||
|
@ -233,6 +278,17 @@ var styles = StyleSheet.create({
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
backgroundColor: 'white',
|
backgroundColor: 'white',
|
||||||
},
|
},
|
||||||
|
statusBar: {
|
||||||
|
height: StatusBar.currentHeight,
|
||||||
|
},
|
||||||
|
drawerStatusBar: {
|
||||||
|
position: 'absolute',
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
height: StatusBar.currentHeight,
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, 0.251)',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// The View that contains both the actual drawer and the main view
|
// The View that contains both the actual drawer and the main view
|
||||||
|
|
Loading…
Reference in New Issue