通过 ToolbarAndroid => onIconClicked 显示 DrawerLayoutAndroid

Show DrawerLayoutAndroid via ToolbarAndroid => onIconClicked

我是 React native(和 React)的新手,正在尝试使用它。

我设法添加了一个可以从屏幕左侧拖动的 DrawerLayout。 但是我想在我的 ToolbarAndroid 中单击我的菜单图标时打开它。

我尝试使用 "refs" 但它似乎不起作用

希望我说得够清楚了。

谢谢

您应该像您提到的那样使用 "refs"。为此,为您的抽屉组件设置 "ref" 属性:

<DrawerLayoutAndroid
   ...
   ref={'DRAWER_REF'}
   ...
/>

然后在您的组件中使用 this.refs 访问它并在该 ref 上调用 openDrawercloseDrawer(例如,您可能希望 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>
    );

  }
});

Full File Gist

只想再补充一个解决方案,尤其是在使用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>