基礎編からの続きです。
シリーズ
- React-Navigatorを利用してみる(基礎編)
- RN応用編1:Drawer Navigatorをハンバーガーメニューで表示させる→この記事
- RN応用編2:TabやDrawerメニューにアイコンを設定する
- RN応用編3:Reduxで値の取り回し
概要
基礎編でDrawer Navigationを追加しましたが、そのままでは、利用者は存在に気づきません。そのため、ヘッダー部分にハンバーガーメニューを追加して、Drawerを開くようにします。
なお、Tab NavigationやSingleページ?(Stack Navigation以外)ではヘッダにメニューを追加できないようなので、その対応方法も書きます。
ひとまずハンバーガーメニューを追加する
アイコンが使えるようにする
ハンバーガーのアイコンを利用したいのでモジュールをinstallします。
npm install --save react-native-vector-icons
実装してみる
実装してみます。
実装する場所は、コンポーネントに直書きするかcreateStackNavigator()の記述をいじるかの2種類あります。
が、ここではコンポーネントに記述してみます(本家サイトがそうしてるので)。
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()での書き方
下記のような感じです。お好みで。
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'
}
);
動作確認
ハンバーガーメニューが表示されました。
Stack Navigator以外でもハンバーガーメニュー(ヘッダに何かを)表示する
ハンバーガーメニューを利用するのならUIの統一性という意味でTabや普通のページ(ここではSingle)でも表示させたいと思うのが人の心と言うものです。ところが、普通にやると表示されません。
普通に記述してみる(表示されない確認)
では、Tab1.jsにStack1.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等でも同様です。
どうやらStack Navigation以外ではヘッダ(少なくともアイコン等)の表示はできないようです。
Stack Navigation以外でもヘッダを表示させる(本題)
Tab Navigatorや一般のページでヘッダを表示させるためには、以下のようにStack Navigatorでラップ(入れ子に)してやればいいようです。なんかHackチックでいやですが仕方ありません。
//Tab
const Tab = createBottomTabNavigator(
{
Tab1: { screen: createStackNavigator({ Tab1: { screen: Tab1 } }) },
Tab2: { screen: createStackNavigator({ Tab2: { screen: Tab2 } }) },
}
);
こうすることでTab1.jsでもハンバーガーメニューが表示されるようになります。
Single1.js等も必要な箇所でラップすることで表示可能となります。
//drawer
const Drawer = createDrawerNavigator(
{
Stacks: { screen: Stack },
Tabs: { screen: Tab },
+ Single1: {
+ screen: createStackNavigator({
+ Single1: { screen: Single1 }
+ })
+ },
Single2: { screen: Single2 }
}
);
これでTab Navigatorや一般ページでもハンバーガーメニューが表示されるようになりました。
Single1.js等にも追加して試してみてください。
雑感
iPhoneのノッチ対応等を考慮すれば、RNを使うのであればおおよそのページをStackNavigatorでラップしておくのもありかなと思っています。
問題は、Redux等でうまく動作するかです(そのうち検証しますが)。