Показать DrawerLayoutAndroid через ToolbarAndroid => onIconClicked
Я новичок в React native (и React), и я немного поиграю с ним.
Мне удалось добавить DrawerLayout, который я могу перетащить слева от экрана.
Однако я бы хотел открыть его, когда я нажимаю значок своего меню в панели инструментов ToolbarAndroid.
Я пытался использовать "refs", но, похоже, не работает
Надеюсь, я достаточно ясен.
Спасибо
Ответы
Ответ 1
Вы должны использовать "refs", как вы уже упоминали. Для этого для вашего компонента ящика установлен атрибут "ref":
<DrawerLayoutAndroid
...
ref={'DRAWER_REF'}
...
/>
Затем в вашем компоненте используйте this.refs
для доступа к нему и вызовите openDrawer
или closeDrawer
в этом ref (например, вы можете иметь элемент Touchable
, который вызовет этот вызов):
this.refs['DRAWER_REF'].openDrawer();
Ответ 2
Используя образец 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>
);
}
});
Полный файл Gist
Ответ 3
Просто хочу добавить другое решение, особенно если Navigator используется для рендеринга сцены.
Если это так, то вышеупомянутые решения не будут работать, поскольку у него нет доступа к ref, указанному в DrawerLayoutAndroid
, и он фактически вернет
"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 с его функцией renderScene:
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}/>
);
}
});
Ответ 4
"undefined не является объектом" . Большинство из нас оказались здесь с вышеупомянутым решением.
Пожалуйста, убедитесь, что вы правильно использовали синтаксис 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>
Ответ 5
Следуя всем этим фрагментам и по-прежнему получая ошибку undefined is not an object
.
Затем нашел этот поток в GitHub, который окончательно решил мою проблему и прекрасно объяснил проблему refs.
Чтобы следовать примеру DrawerLayoutAndroid
в документации React Native (http://facebook.github.io/react-native/docs/drawerlayoutandroid.html), это код, который работает:
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>
);
}