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;
|
||||
}}
|
||||
ref={(drawer) => { this.drawer = drawer; }}
|
||||
renderNavigationView={this._renderDrawerContent.bind(this, onNavigate)}>
|
||||
renderNavigationView={this._renderDrawerContent.bind(this, onNavigate)}
|
||||
statusBarBackgroundColor="#589c90">
|
||||
{this._renderNavigation(navigationState, onNavigate)}
|
||||
</DrawerLayoutAndroid>
|
||||
);
|
||||
|
@ -79,15 +80,17 @@ class UIExplorerApp extends React.Component {
|
|||
|
||||
_renderDrawerContent(onNavigate) {
|
||||
return (
|
||||
<UIExplorerExampleList
|
||||
list={UIExplorerList}
|
||||
displayTitleRow={true}
|
||||
disableSearch={true}
|
||||
onNavigate={(action) => {
|
||||
this.drawer && this.drawer.closeDrawer();
|
||||
onNavigate(action);
|
||||
}}
|
||||
/>
|
||||
<View style={styles.drawerContentWrapper}>
|
||||
<UIExplorerExampleList
|
||||
list={UIExplorerList}
|
||||
displayTitleRow={true}
|
||||
disableSearch={true}
|
||||
onNavigate={(action) => {
|
||||
this.drawer && this.drawer.closeDrawer();
|
||||
onNavigate(action);
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -113,9 +116,6 @@ class UIExplorerApp extends React.Component {
|
|||
const ExampleComponent = UIExplorerExampleList.makeRenderable(ExampleModule);
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<StatusBar
|
||||
backgroundColor="#589c90"
|
||||
/>
|
||||
<ToolbarAndroid
|
||||
logo={require('image!launcher_icon')}
|
||||
navIcon={require('image!ic_menu_black_24dp')}
|
||||
|
@ -131,9 +131,6 @@ class UIExplorerApp extends React.Component {
|
|||
}
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<StatusBar
|
||||
backgroundColor="#589c90"
|
||||
/>
|
||||
<ToolbarAndroid
|
||||
logo={require('image!launcher_icon')}
|
||||
navIcon={require('image!ic_menu_black_24dp')}
|
||||
|
@ -181,6 +178,10 @@ const styles = StyleSheet.create({
|
|||
backgroundColor: '#E9EAED',
|
||||
height: 56,
|
||||
},
|
||||
drawerContentWrapper: {
|
||||
paddingTop: StatusBar.currentHeight,
|
||||
backgroundColor: 'white',
|
||||
},
|
||||
});
|
||||
|
||||
AppRegistry.registerComponent('UIExplorerApp', () => UIExplorerApp);
|
||||
|
|
|
@ -10,9 +10,12 @@
|
|||
*/
|
||||
'use strict';
|
||||
|
||||
var ColorPropType = require('ColorPropType');
|
||||
var NativeMethodsMixin = require('NativeMethodsMixin');
|
||||
var Platform = require('Platform');
|
||||
var React = require('React');
|
||||
var ReactPropTypes = require('ReactPropTypes');
|
||||
var StatusBar = require('StatusBar');
|
||||
var StyleSheet = require('StyleSheet');
|
||||
var UIManager = require('UIManager');
|
||||
var View = require('View');
|
||||
|
@ -25,12 +28,6 @@ var requireNativeComponent = require('requireNativeComponent');
|
|||
var RK_DRAWER_REF = 'drawerlayout';
|
||||
var INNERVIEW_REF = 'innerView';
|
||||
|
||||
var DrawerLayoutValidAttributes = {
|
||||
drawerWidth: true,
|
||||
drawerPosition: true,
|
||||
drawerLockMode: true
|
||||
};
|
||||
|
||||
var DRAWER_STATES = [
|
||||
'Idle',
|
||||
'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.
|
||||
*/
|
||||
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],
|
||||
|
||||
getInitialState: function() {
|
||||
return {statusBarBackgroundColor: undefined};
|
||||
},
|
||||
|
||||
getInnerViewNode: function() {
|
||||
return this.refs[INNERVIEW_REF].getInnerViewNode();
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
this._updateStatusBarBackground();
|
||||
},
|
||||
|
||||
componentDidReceiveProps: function() {
|
||||
this._updateStatusBarBackground();
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var drawStatusBar = Platform.Version >= 21 && this.props.statusBarBackgroundColor;
|
||||
var drawerViewWrapper =
|
||||
<View style={[styles.drawerSubview, {width: this.props.drawerWidth}]} collapsable={false}>
|
||||
{this.props.renderNavigationView()}
|
||||
{drawStatusBar && <View style={styles.drawerStatusBar} />}
|
||||
</View>;
|
||||
var childrenWrapper =
|
||||
<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}
|
||||
</View>;
|
||||
return (
|
||||
|
@ -213,6 +241,23 @@ var DrawerLayoutAndroid = React.createClass({
|
|||
_getDrawerLayoutHandle: function() {
|
||||
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({
|
||||
|
@ -233,6 +278,17 @@ var styles = StyleSheet.create({
|
|||
bottom: 0,
|
||||
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
|
||||
|
|
Loading…
Reference in New Issue