Подтвердить что ты не робот

Показать DrawerLayoutAndroid через ToolbarAndroid => onIconClicked

Я новичок в React native (и React), и я немного поиграю с ним.

Мне удалось добавить DrawerLayout, который я могу перетащить слева от экрана. Однако я бы хотел открыть его, когда я нажимаю значок своего меню в панели инструментов ToolbarAndroid.

Я пытался использовать "refs", но, похоже, не работает

Надеюсь, я достаточно ясен.

Спасибо

4b9b3361

Ответ 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>
  );
}