LoginSignup
9
9

More than 3 years have passed since last update.

RN応用編1:Drawer Navigatorをハンバーガーメニューで表示させる

Last updated at Posted at 2018-10-28

基礎編からの続きです。

シリーズ

概要

基礎編でDrawer Navigationを追加しましたが、そのままでは、利用者は存在に気づきません。そのため、ヘッダー部分にハンバーガーメニューを追加して、Drawerを開くようにします。

スクリーンショット 2018-10-28 8.55.27.png

なお、Tab NavigationやSingleページ?(Stack Navigation以外)ではヘッダにメニューを追加できないようなので、その対応方法も書きます。

ひとまずハンバーガーメニューを追加する

アイコンが使えるようにする

ハンバーガーのアイコンを利用したいのでモジュールをinstallします。

npm install --save react-native-vector-icons

実装してみる

実装してみます。
実装する場所は、コンポーネントに直書きするかcreateStackNavigator()の記述をいじるかの2種類あります。
が、ここではコンポーネントに記述してみます(本家サイトがそうしてるので)。

Stack1.js
import React from 'react';
import { View, Text, Button } from 'react-native';
+import Icon from 'react-native-vector-icons/FontAwesome';

export default class Stack1 extends React.Component {
+
+    static navigationOptions = ({navigation}) => ({
+        title:'Stack1',
+        headerLeft:(
+            <Icon name="bars" size={24} onPress={()=>{navigation.openDrawer()}} style={{paddingLeft:20}}/>
+        ),
+    });

    render() {
        return (
            <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
                <Text>Stack1</Text>
                <Button
                    title='GoTo Stack2'
                    onPress={() => this.props.navigation.navigate('Stack2')}
                />
            </View>
        );
    }
}

参考: createStackNavigator()での書き方

下記のような感じです。お好みで。

App.js(抜粋)
const Stack = createStackNavigator(
  {
    Stack1: {
      screen: Stack1,
      navigationOptions: ({ navigation }) => ({
        headerLeft: (
          <Icon name="bars" size={24} onPress={() => { navigation.openDrawer() }} style={{ paddingLeft: 20 }} />
        ),
      })
    },
    Stack2: { screen: Stack2 },
  },
  {
    initialRouteName: 'Stack1'
  }
);

動作確認

スクリーンショット 2018-10-27 20.22.36.png

ハンバーガーメニューが表示されました。

Stack Navigator以外でもハンバーガーメニュー(ヘッダに何かを)表示する

ハンバーガーメニューを利用するのならUIの統一性という意味でTabや普通のページ(ここではSingle)でも表示させたいと思うのが人の心と言うものです。ところが、普通にやると表示されません。

普通に記述してみる(表示されない確認)

では、Tab1.jsにStack1.jsと同様な記述を追加してみます。

Tab1.js
import React from 'react';
import { View, Text, Button } from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome';

export default class Tab1 extends React.Component {

    static navigationOptions = ({navigation}) => ({
        title:'Tab1',
        headerLeft:(
            <Icon name="bars" size={24} onPress={()=>{navigation.openDrawer()}} style={{paddingLeft:20}}/>
        ),
    });

    render() {
        return (
            <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
                <Text>Tab1</Text>
            </View>
        );
    }
}

実行してもハンバーガーメニューは表示されません。Sigle1.js等でも同様です。

スクリーンショット 2018-10-27 22.01.35.png

どうやらStack Navigation以外ではヘッダ(少なくともアイコン等)の表示はできないようです。

Stack Navigation以外でもヘッダを表示させる(本題)

Tab Navigatorや一般のページでヘッダを表示させるためには、以下のようにStack Navigatorでラップ(入れ子に)してやればいいようです。なんかHackチックでいやですが仕方ありません。

App.js(抜粋)
//Tab
const Tab = createBottomTabNavigator(
    {
        Tab1: { screen: createStackNavigator({ Tab1: { screen: Tab1 } }) },
        Tab2: { screen: createStackNavigator({ Tab2: { screen: Tab2 } }) },
    }
);

こうすることでTab1.jsでもハンバーガーメニューが表示されるようになります。

スクリーンショット 2018-10-27 22.10.06.png

Single1.js等も必要な箇所でラップすることで表示可能となります。

App.js(抜粋)
//drawer
const Drawer = createDrawerNavigator(
  {
    Stacks: { screen: Stack },
    Tabs: { screen: Tab },
+    Single1: {
+      screen: createStackNavigator({
+        Single1: { screen: Single1 }
+      })
+    },
    Single2: { screen: Single2 }
  }
);

スクリーンショット 2018-10-27 22.13.39.png

これでTab Navigatorや一般ページでもハンバーガーメニューが表示されるようになりました。
Single1.js等にも追加して試してみてください。

雑感

iPhoneのノッチ対応等を考慮すれば、RNを使うのであればおおよそのページをStackNavigatorでラップしておくのもありかなと思っています。
問題は、Redux等でうまく動作するかです(そのうち検証しますが)。

リンク

RN応用編2:TabやDrawerメニューにアイコンを設定する

9
9
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
9