2日目: react-navigationでアイコン付きのタブUIを作る
React Native100日チャレンジ2日目の記事になります。
Githubリポジトリはこちら → https://github.com/masarufuruya/100days-challenge-react-native
昨日はreact-navigationの環境構築とstack navigatorで画面を作りました。
本日は昨日の環境構築でハマったbottom-tabsがすんなり動いたので、タブUIについて書いていきます。
expo-cliを3.28.1→3.28.5へアップデートしたのが、良かったのかな?
シンプルなタブUIを実装
まずは@react-navigation/bottom-tabsをインストールします。
npm install @react-navigation/bottom-tabs
インストールができたら、公式サイトのサンプルを元に動かします。
import * as React from 'react';
import { View, Text } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
function HomeScreen() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
</View>
);
}
function SettingsScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings Screen</Text>
</View>
);
}
const Stack = createStackNavigator();
const Tab = createBottomTabNavigator();
function App() {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
{/* <Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
</Stack.Navigator> */}
</NavigationContainer>
);
}
export default App;
こんな感じのシンプルなタブができました。
次にアイコンをタブに表示していきます。
ReactNativeでアイコンを使う場合はreact-native-vector-iconsをよく使うと思いますが、expoでは公式サポートされています。
公式に書いてありますが、デフォルトでexpoパッケージに入っているので、新しくインストールする必要はありません。
最初、ここを勘違いしていて自分で@expo/vector-iconsをnpm installしたら、おかしいエラーが色々でてハマリました... (恐らくbottom-tabsが動かなかったのもこれが原因かも)
タブにアイコンを追加
react-navigationの公式のサンプルを参考に書き換えます。
Ioniconsを使う場合の例ですね。
import * as React from 'react';
import { View, Text } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { Ionicons } from '@expo/vector-icons';
function HomeScreen() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
</View>
);
}
function SettingsScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings Screen</Text>
</View>
);
}
const Stack = createStackNavigator();
const Tab = createBottomTabNavigator();
function App() {
return (
<NavigationContainer>
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let iconName;
if (route.name === 'Home') {
iconName = focused
? 'ios-information-circle'
: 'ios-information-circle-outline';
} else if (route.name === 'Settings') {
iconName = focused ? 'ios-list-box' : 'ios-list';
}
return <Ionicons name={iconName} size={size} color={color} />;
},
})}
tabBarOptions={{
activeTintColor: 'tomato',
inactiveTintColor: 'gray',
}}
>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
{/* <Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
</Stack.Navigator> */}
</NavigationContainer>
);
}
export default App;
これでこんな感じの画面が作れるようになりました。ちゃんとタブの遷移ができてアクティブなアイコンの色が変わります。
おわりに
いやー本当expoは神ですね。素のReactNativeの時はvector-iconの設定で結構時間を吸われた記憶があるんですけど、速攻で作れてしまいました。
次はフォーム画面が作りたいので、次回はNativeBaseにHello worldしてみたいと思います。ではまた明日!
この記事が気に入ったらサポートをしてみませんか?