通过 ToolbarAndroid => onIconClicked 显示 DrawerLayoutAndroid
Show DrawerLayoutAndroid via ToolbarAndroid => onIconClicked
我是 React native(和 React)的新手,正在尝试使用它。
我设法添加了一个可以从屏幕左侧拖动的 DrawerLayout。
但是我想在我的 ToolbarAndroid 中单击我的菜单图标时打开它。
我尝试使用 "refs" 但它似乎不起作用
希望我说得够清楚了。
谢谢
您应该像您提到的那样使用 "refs"。为此,为您的抽屉组件设置 "ref" 属性:
<DrawerLayoutAndroid
...
ref={'DRAWER_REF'}
...
/>
然后在您的组件中使用 this.refs
访问它并在该 ref 上调用 openDrawer
或 closeDrawer
(例如,您可能希望 Touchable
元素将触发这个电话):
this.refs['DRAWER_REF'].openDrawer();
使用 ReactNative 示例,您可以这样做:
var DrawerTest = React.createClass({
openDrawer:function() {
this.refs['DRAWER'].openDrawer()
},
render: function() {
var navigationView = (
<View style={{flex: 1, backgroundColor: '#fff'}}>
<Text style={{margin: 10, fontSize: 15, textAlign: 'left'}}>I'm in the Drawer!</Text>
</View>
);
return (
<DrawerLayoutAndroid
drawerWidth={300}
ref={'DRAWER'}
drawerPosition={DrawerLayoutAndroid.positions.Left}
renderNavigationView={() => navigationView}>
<View style={{flex: 1, alignItems: 'center'}}>
<Text style={{margin: 10, fontSize: 15, textAlign: 'right'}}>Hello</Text>
<Text style={{margin: 10, fontSize: 15, textAlign: 'right'}}>World!</Text>
<TouchableHighlight onPress={this.openDrawer}>
<Text>{'Open Drawer'}</Text>
</TouchableHighlight>
</View>
</DrawerLayoutAndroid>
);
}
});
只想再补充一个解决方案,尤其是在使用Navigator渲染场景的时候。
如果是这种情况,那么上述解决方案将不起作用,因为它无法访问 DrawerLayoutAndroid
中指定的 ref,而实际上它会 return
"undefined is not an object (evaluating 'this.refs['DRAWER_REF']')"
或类似的东西。
解决方案:
创建我们自己的工具栏,以便我们可以将渲染组件传递给它。
MyToolbar.js
... import stuff ...
module.exports = React.createClass({
render: function() {
return (
<ToolbarAndroid
title={this.props.title}
navIcon = {{uri: "ic_menu_white_24dp", isStatic: true}}
style = {styles.toolbar}
titleColor='#FFFFFF'
onIconClicked={this._onIconClicked}/>
);
},
_onIconClicked: function(){
this.props.sidebarRef.refs['DRAWER'].openDrawer();
// sidebarRef is the rendering component we're passing
}
});
OpenDrawerFromToolbar.js
...
module.exports = React.createClass({
render: function() {
var navigationView = (
<View style={{flex: 1, backgroundColor: '#fff'}}>
<Text style={{margin: 10, fontSize: 15, textAlign: 'left'}}>In the Drawer!</Text>
</View>
);
return (
<View style={styles.container}>
<DrawerLayoutAndroid drawerWidth = {300}
drawerPosition = {DrawerLayoutAndroid.positions.Left}
renderNavigationView = {() => navigationView}
ref={'DRAWER'}>
<MyToolbar style={styles.toolbar}
title={'My Awesome App'}
navigator={this.props.navigator}
sidebarRef={this}/> // pass the component to MyToolbar
<View style = {{flex: 1, alignItems: 'center'}}>
<Text style = {{margin: 10, fontSize: 15, textAlign: 'right'}}>Hello</Text>
<Text style = {{margin: 10, fontSize: 15, textAlign: 'right'}}>World!</Text>
</View>
</DrawerLayoutAndroid>
</View>
);
},
_setDrawer: function() {
this.refs['DRAWER'].openDrawer();
}
});
然后我们的 Navigator 组件及其 renderingScene 函数将起作用:
module.exports = React.createClass({
render: function() {
return (
<Navigator
style = {styles.container}
initialRoute = {{ name: 'openDrawerFromToolbar', index: 0 }}
renderScene = {this.navigatorRenderScene}
configureScene={ () => { return Navigator.SceneConfigs.PushFromRight; }}/>
);
},
navigatorRenderScene: function(route, navigator) {
_navigator = navigator;
return (
<OpenDrawerFromToolbar
route={route}
navigator={navigator}
data={route.data}/>
);
}
});
按照所有这些片段进行操作,仍然出现 undefined is not an object
错误。
然后在GitHub上找到了this thread,终于解决了我的问题,完美的解释了refs的问题。
遵循 React Native 文档 (http://facebook.github.io/react-native/docs/drawerlayoutandroid.html) 上的 DrawerLayoutAndroid
示例,这是有效的代码:
constructor() {
super();
this.openDrawer = this.openDrawer.bind(this);
}
openDrawer() {
this.drawer.openDrawer();
}
render() {
var navigationView = (
<View style={{flex: 1, backgroundColor: '#fff'}}>
<Text style={{margin: 10, fontSize: 15, textAlign: 'left'}}>I'm in the Drawer!</Text>
</View>
);
return (
<DrawerLayoutAndroid
drawerWidth={300}
ref={(_drawer) => this.drawer = _drawer}
drawerPosition={DrawerLayoutAndroid.positions.Left}
renderNavigationView={() => navigationView}>
<View style={{flex: 1, alignItems: 'center'}}>
<Text style={{margin: 10, fontSize: 15, textAlign: 'right'}}>Hello</Text>
<Text style={{margin: 10, fontSize: 15, textAlign: 'right'}}>World!</Text>
<TouchableHighlight onPress={this.openDrawer}>
<Text>{'Open Drawer'}</Text>
</TouchableHighlight>
</View>
</DrawerLayoutAndroid>
);
}
"undefined is not an object" - 我们中的大多数人最终都得到了上述解决方案。
请确保您已正确使用如下所述的 ES6 语法。
语法不正确:
onPress={this.drawer()}
正确的语法:
onPress={() => this.drawer()}
代码:
<DrawerLayoutAndroid
...
ref={'DRAWER_REF'}
...
/>
--------------------------------------------------
//Write this just before render() method
drawer = () => {
this.refs['DRAWER_REF'].openDrawer();
}
--------------------------------------------------
<TouchableHighlight onPress={() => this.drawer()}>
<Icon name="bars" size={30} color="#900"/>
</TouchableHighlight>
我是 React native(和 React)的新手,正在尝试使用它。
我设法添加了一个可以从屏幕左侧拖动的 DrawerLayout。 但是我想在我的 ToolbarAndroid 中单击我的菜单图标时打开它。
我尝试使用 "refs" 但它似乎不起作用
希望我说得够清楚了。
谢谢
您应该像您提到的那样使用 "refs"。为此,为您的抽屉组件设置 "ref" 属性:
<DrawerLayoutAndroid
...
ref={'DRAWER_REF'}
...
/>
然后在您的组件中使用 this.refs
访问它并在该 ref 上调用 openDrawer
或 closeDrawer
(例如,您可能希望 Touchable
元素将触发这个电话):
this.refs['DRAWER_REF'].openDrawer();
使用 ReactNative 示例,您可以这样做:
var DrawerTest = React.createClass({
openDrawer:function() {
this.refs['DRAWER'].openDrawer()
},
render: function() {
var navigationView = (
<View style={{flex: 1, backgroundColor: '#fff'}}>
<Text style={{margin: 10, fontSize: 15, textAlign: 'left'}}>I'm in the Drawer!</Text>
</View>
);
return (
<DrawerLayoutAndroid
drawerWidth={300}
ref={'DRAWER'}
drawerPosition={DrawerLayoutAndroid.positions.Left}
renderNavigationView={() => navigationView}>
<View style={{flex: 1, alignItems: 'center'}}>
<Text style={{margin: 10, fontSize: 15, textAlign: 'right'}}>Hello</Text>
<Text style={{margin: 10, fontSize: 15, textAlign: 'right'}}>World!</Text>
<TouchableHighlight onPress={this.openDrawer}>
<Text>{'Open Drawer'}</Text>
</TouchableHighlight>
</View>
</DrawerLayoutAndroid>
);
}
});
只想再补充一个解决方案,尤其是在使用Navigator渲染场景的时候。
如果是这种情况,那么上述解决方案将不起作用,因为它无法访问 DrawerLayoutAndroid
中指定的 ref,而实际上它会 return
"undefined is not an object (evaluating 'this.refs['DRAWER_REF']')"
或类似的东西。
解决方案:
创建我们自己的工具栏,以便我们可以将渲染组件传递给它。
MyToolbar.js
... import stuff ...
module.exports = React.createClass({
render: function() {
return (
<ToolbarAndroid
title={this.props.title}
navIcon = {{uri: "ic_menu_white_24dp", isStatic: true}}
style = {styles.toolbar}
titleColor='#FFFFFF'
onIconClicked={this._onIconClicked}/>
);
},
_onIconClicked: function(){
this.props.sidebarRef.refs['DRAWER'].openDrawer();
// sidebarRef is the rendering component we're passing
}
});
OpenDrawerFromToolbar.js
...
module.exports = React.createClass({
render: function() {
var navigationView = (
<View style={{flex: 1, backgroundColor: '#fff'}}>
<Text style={{margin: 10, fontSize: 15, textAlign: 'left'}}>In the Drawer!</Text>
</View>
);
return (
<View style={styles.container}>
<DrawerLayoutAndroid drawerWidth = {300}
drawerPosition = {DrawerLayoutAndroid.positions.Left}
renderNavigationView = {() => navigationView}
ref={'DRAWER'}>
<MyToolbar style={styles.toolbar}
title={'My Awesome App'}
navigator={this.props.navigator}
sidebarRef={this}/> // pass the component to MyToolbar
<View style = {{flex: 1, alignItems: 'center'}}>
<Text style = {{margin: 10, fontSize: 15, textAlign: 'right'}}>Hello</Text>
<Text style = {{margin: 10, fontSize: 15, textAlign: 'right'}}>World!</Text>
</View>
</DrawerLayoutAndroid>
</View>
);
},
_setDrawer: function() {
this.refs['DRAWER'].openDrawer();
}
});
然后我们的 Navigator 组件及其 renderingScene 函数将起作用:
module.exports = React.createClass({
render: function() {
return (
<Navigator
style = {styles.container}
initialRoute = {{ name: 'openDrawerFromToolbar', index: 0 }}
renderScene = {this.navigatorRenderScene}
configureScene={ () => { return Navigator.SceneConfigs.PushFromRight; }}/>
);
},
navigatorRenderScene: function(route, navigator) {
_navigator = navigator;
return (
<OpenDrawerFromToolbar
route={route}
navigator={navigator}
data={route.data}/>
);
}
});
按照所有这些片段进行操作,仍然出现 undefined is not an object
错误。
然后在GitHub上找到了this thread,终于解决了我的问题,完美的解释了refs的问题。
遵循 React Native 文档 (http://facebook.github.io/react-native/docs/drawerlayoutandroid.html) 上的 DrawerLayoutAndroid
示例,这是有效的代码:
constructor() {
super();
this.openDrawer = this.openDrawer.bind(this);
}
openDrawer() {
this.drawer.openDrawer();
}
render() {
var navigationView = (
<View style={{flex: 1, backgroundColor: '#fff'}}>
<Text style={{margin: 10, fontSize: 15, textAlign: 'left'}}>I'm in the Drawer!</Text>
</View>
);
return (
<DrawerLayoutAndroid
drawerWidth={300}
ref={(_drawer) => this.drawer = _drawer}
drawerPosition={DrawerLayoutAndroid.positions.Left}
renderNavigationView={() => navigationView}>
<View style={{flex: 1, alignItems: 'center'}}>
<Text style={{margin: 10, fontSize: 15, textAlign: 'right'}}>Hello</Text>
<Text style={{margin: 10, fontSize: 15, textAlign: 'right'}}>World!</Text>
<TouchableHighlight onPress={this.openDrawer}>
<Text>{'Open Drawer'}</Text>
</TouchableHighlight>
</View>
</DrawerLayoutAndroid>
);
}
"undefined is not an object" - 我们中的大多数人最终都得到了上述解决方案。
请确保您已正确使用如下所述的 ES6 语法。
语法不正确:
onPress={this.drawer()}
正确的语法:
onPress={() => this.drawer()}
代码:
<DrawerLayoutAndroid
...
ref={'DRAWER_REF'}
...
/>
--------------------------------------------------
//Write this just before render() method
drawer = () => {
this.refs['DRAWER_REF'].openDrawer();
}
--------------------------------------------------
<TouchableHighlight onPress={() => this.drawer()}>
<Icon name="bars" size={30} color="#900"/>
</TouchableHighlight>