web-dev-qa-db-fra.com

Afficher DrawerLayoutAndroid via ToolbarAndroid => onIconClicked

Je suis nouveau dans React native (et React) et je joue un peu avec elle.

J'ai réussi à ajouter DrawerLayout que je peux faire glisser depuis la gauche de mon écran. Cependant, j'aimerais l'ouvrir lorsque je clique sur mon icône de menu dans ma barre d'outils Android.

J'ai essayé d'utiliser "refs" mais cela ne semble pas fonctionner

J'espère que je suis assez clair.

Je vous remercie

18
Maslow

Vous devriez utiliser "refs" comme vous l'avez mentionné. Pour ce faire, pour votre composant tiroir, définissez l'attribut "ref":

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

Ensuite, dans votre composant, utilisez this.refs pour y accéder et appelez openDrawer ou closeDrawer sur cette référence (par exemple, vous voudrez peut-être avoir un élément Touchable qui déclenchera cet appel):

this.refs['DRAWER_REF'].openDrawer();
30
kzzzf

En utilisant l'exemple ReactNative, vous pouvez faire comme ça:

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>
    );

  }
});

Fichier complet Gist

8
Tiago Gouvêa

Je veux juste ajouter une autre solution, en particulier lorsque Navigator est utilisé pour rendre la scène.

Si tel est le cas, les solutions ci-dessus ne fonctionneront pas car il n’a pas accès à la référence spécifiée dans la variable DrawerLayoutAndroid et elle retournera en fait.

"undefined is not an object (evaluating 'this.refs['DRAWER_REF']')"

ou quelque chose comme ça.

Solution:

Créez notre propre barre d’outils afin que nous puissions lui transmettre notre composant de rendu.

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();
  }
});

Ensuite, notre composant Navigator avec sa fonction renderingScene fonctionnera:

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}/>
      );
  }
});
2
Fadils

"indéfini n'est pas un objet" - La plupart d'entre nous s'est retrouvé ici avec une solution ci-dessus.

Assurez-vous que vous avez correctement utilisé la syntaxe ES6 décrite ci-dessous.

Syntaxe incorrecte:

onPress={this.drawer()}

Corrigez la syntaxe:

onPress={() => this.drawer()}

Code:

<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>
1
Edison D'souza

En suivant tous ces extraits et en obtenant toujours l'erreur undefined is not an object.

Puis j'ai trouvé ce fil sur GitHub qui a finalement résolu mon problème et explique parfaitement le problème refs .

Pour suivre l’exemple DrawerLayoutAndroid de la documentation React Native ( http://facebook.github.io/react-native/docs/drawerlayoutandroid.html ), c’est le code qui fonctionne:

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>
  );
}
0
GuGuss