ドロワー・ナビゲータの使用方法

ここでは現代的でマテリアルデザインな UI を作るのに非常に重要な、 Drawer Navigator (ドロワー・ナビゲータ) について説明します。

ドロワーは次のようなスライドして表示されるメニューのことです。

ここで作成するサンプルは次のような画面です。

まずホームスクリーンがあります。

左上のアイコンをタップすると、ドロワーメニューが表示されます。

ここで例えば "Games" をタップします。すると、Game のホームスクリーンが表示されます。

上の画面の "Game ABC" とかかれたボタンをタップすると、"Game ABC" 画面が表示されます。

ここでこの "Game ABC" 画面の左上は戻る矢印が表示されていることに注意してください。 これはスクリーンが積み重なるスタックナビゲータであることを示しています。

ちなみに一番初めに表示された Home スクリーンにもボタンがありましたが、そのボタンをタップすると Home 画面にスクリーンが積み重なるようになってます。

スタックナビゲータについては、「スタックナビゲータの使用方法」をみてください。

非常に一般的なナビゲーションですね。

これを実現する方法を説明します。

まずは、プロジェクトを作成しましょう。アイコンが必要なので、react-native-vector-icons も取り込んでいます。

$ react-native init nav3
$ cd nav3
$ npm install react-navigation --save
$ npm install react-native-vector-icons --save
$ react-native link react-native-vector-icons

App.js は次の通りです。

import React, { Component } from 'react';
import {
  AppRegistry,
  Button,
  ScrollView,
  StyleSheet,
  Text,
  View
} from 'react-native';
import {
  StackNavigator,
  DrawerNavigator,
  DrawerItems
} from 'react-navigation';
import Icon from 'react-native-vector-icons/FontAwesome';

///////////////////////////////////////////////////////////////////////
//
// Styles
//

const styles = StyleSheet.create({
  view1: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center'
  },
  text1:{
    fontSize: 26,
  },
  icon1:{
    marginLeft: 16,
  },
  headerHome: {
    backgroundColor: '#CDDC39',
  },
  headerGame: {
    backgroundColor: '#4CAF50',
  },
  headerBook: {
    backgroundColor: '#FFC107',
  },
})

///////////////////////////////////////////////////////////////////////
//
// HOME
//

class HomeScreen extends React.Component {

  static navigationOptions = ({navigation}) => ({
    title:'Home',
    drawerIcon: <Icon name="home" size={24} color="#4CAF50"/>,
    headerStyle: styles.headerHome,
    headerLeft: (
      <Icon name="bars" size={24}
        style={styles.icon1}
        onPress={()=>{navigation.navigate('DrawerOpen')}} />
    ),
  });

  render(){
    const { navigate } = this.props.navigation;
    return (
      <View style={styles.view1}>
        <Text style={styles.text1}>Home</Text>
        <Button title="Next" onPress={()=>navigate('HomeNext')}/>
      </View>
    );
  }
}

///////////////////////////////////////////////////////////////////////
//
// HOME > Next
//

class HomeNextScreen extends React.Component {
  static navigationOptions = {
    title:'Home Next',
    headerStyle: styles.headerHome,
  };

  render() {
    return (
      <View style={styles.view1}>
        <Text style={styles.text1}>Next</Text>
      </View>
    );
  }
}


///////////////////////////////////////////////////////////////////////
//
// GAME
//

class GameHomeScreen extends React.Component {

  static navigationOptions = ({navigation}) => ({
    title:'Games',
    drawerIcon: <Icon name="gamepad" size={24} color="#FF5722"/>,
    headerStyle: styles.headerGame,
    headerLeft: (
      <Icon name="bars" size={24}
        style={styles.icon1}
        onPress={()=>{navigation.navigate('DrawerOpen')}} />
    ),
  });

  render(){
    const { navigate } = this.props.navigation;
    return (
      <View style={styles.view1}>
        <Text style={styles.text1}>Game Home</Text>
        <Button title="Start ABC" onPress={()=>navigate('GameABC')}/>
      </View>
    );
  }
}

///////////////////////////////////////////////////////////////////////
//
// GAME > GAME ABC
//

class GameABCScreen extends React.Component {

  static navigationOptions = ({navigation}) => ({
    title:'Game ABC',
    headerStyle: styles.headerGame,
  });

  render(){
    return (
      <View style={styles.view1}>
        <Text style={styles.text1}>Game ABC</Text>
      </View>
    );
  }
}


///////////////////////////////////////////////////////////////////////
//
// BOOKS
//

class BookHomeScreen extends React.Component {
  static navigationOptions = ({navigation}) => ({
    title:'Books',
    drawerLabel: 'Books - Drawer Label',
    drawerIcon: <Icon name="book" size={24} color="#795548"/>,
    headerStyle: styles.headerBook,
    headerLeft: (
      <Icon name="bars" size={24}
        style={styles.icon1}
        onPress={()=>{navigation.navigate('DrawerOpen')}} />
    ),
  });

  render(){
    return (
      <View style={styles.view1}>
        <Text style={styles.text1}>Books</Text>
      </View>
    );
  }
}

///////////////////////////////////////////////////////////////////////
//
// Define Stack Structure
//

const HomeStack = StackNavigator({
  Home: { screen: HomeScreen, },
  HomeNext: { screen: HomeNextScreen, },
});

const GameStack = StackNavigator({
  GameHome: { screen: GameHomeScreen, },
  GameABC: { screen: GameABCScreen, }
});

const BookStack = StackNavigator({
  BookHome: { screen: BookHomeScreen, }
});

///////////////////////////////////////////////////////////////////////
//
// Drawer
//

const MyApp = DrawerNavigator({
    HomeStack: { screen: HomeStack, },
    GameStack: { screen: GameStack, },
    BookStack: { screen: BookStack, }
  },
  {
    drawerWidth: 300,
    contentComponent: props => (
      <ScrollView>
        <View style={{padding:16,}}>
          <Text style={{fontSize:24}}>DRAWER TEST</Text>
        </View>
        <DrawerItems {...props} />
      </ScrollView>
    ),
  }
);

///////////////////////////////////////////////////////////////////////
//
// export
//

export default MyApp;

index.js は次の通りです。

import { AppRegistry } from 'react-native';
import MyApp from './App';
AppRegistry.registerComponent('nav3', () => MyApp);

ドロワーは、DrawerNavigator として実装します。

ドロワーのメニュー項目に上記のように StackNavigator を設定することで、そのドロワーメニュー内でスタックする画面遷移になります。

また、ドロワー上部に "DRAWER TEST" という文字を記載していますが、これは DrawerNavigatorcontentComponent でカスタマイズすることが可能です。

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 React 入門