メインコンテンツへスキップ
バージョン: 6.x

タブナビゲーション

モバイルアプリで最も一般的なナビゲーションスタイルは、おそらくタブベースのナビゲーションです。これは、画面の下部またはヘッダーの下(またはヘッダーの代わり)の上部にあるタブにすることができます。

このガイドでは、createBottomTabNavigatorについて説明します。また、createMaterialBottomTabNavigatorおよびcreateMaterialTopTabNavigatorを使用して、アプリケーションにタブを追加することもできます。

続行する前に、まず@react-navigation/bottom-tabsをインストールしてください

npm install @react-navigation/bottom-tabs

タブベースのナビゲーションの最小限の例

import * as React from 'react';
import { Text, View } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

function HomeScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home!</Text>
</View>
);
}

function SettingsScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings!</Text>
</View>
);
}

const Tab = createBottomTabNavigator();

export default function App() {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}

Tabs minimal

外観のカスタマイズ

これは、スタックナビゲーターをカスタマイズする方法と似ています。タブナビゲーターを初期化するときに設定されるプロパティと、optionsで画面ごとにカスタマイズできるプロパティがあります。

// You can import Ionicons from @expo/vector-icons/Ionicons if you use Expo or
// react-native-vector-icons/Ionicons otherwise.
import Ionicons from 'react-native-vector-icons/Ionicons';

// (...)

export default 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' : 'ios-list-outline';
}

// You can return any component that you like here!
return <Ionicons name={iconName} size={size} color={color} />;
},
tabBarActiveTintColor: 'tomato',
tabBarInactiveTintColor: 'gray',
})}
>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}

詳しく見ていきましょう

  • tabBarIconは、ボトムタブナビゲーターでサポートされているオプションです。したがって、optionsプロパティで画面コンポーネントで使用できることはわかっていますが、この場合は便宜上、アイコン構成を集中させるためにTab.NavigatorscreenOptionsプロパティに配置することを選択しました。
  • tabBarIconは、focused状態、color、およびsizeパラメーターが与えられる関数です。さらに構成を見ると、tabBarActiveTintColortabBarInactiveTintColorが表示されます。これらはデフォルトでiOSプラットフォームのデフォルトになりますが、ここで変更できます。tabBarIconに渡されるcolorは、focused状態(フォーカスされている場合はアクティブ)に応じて、アクティブまたは非アクティブのいずれかです。sizeは、タブバーで想定されるアイコンのサイズです。
  • createBottomTabNavigatorの構成オプションの詳細については、完全なAPIリファレンスをお読みください。

アイコンにバッジを追加する

アイコンにバッジを追加したい場合があります。tabBarBadgeオプションを使用して実行できます

<Tab.Screen name="Home" component={HomeScreen} options={{ tabBarBadge: 3 }} />

UIの観点からはこのコンポーネントはすぐに使用できますが、React ContextReduxMobX、またはイベントエミッターを使用するなどして、バッジの数を適切に別の場所から渡す方法を見つける必要があります。

Tabs with badges

タブ間の移動

あるタブから別のタブへの切り替えは、おなじみのAPIであるnavigation.navigateで行います。

function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home!</Text>
<Button
title="Go to Settings"
onPress={() => navigation.navigate('Settings')}
/>
</View>
);
}

function SettingsScreen({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings!</Text>
<Button title="Go to Home" onPress={() => navigation.navigate('Home')} />
</View>
);
}

各タブのスタックナビゲーター

多くの場合、タブには1つの画面だけが表示されるわけではありません。たとえば、Twitterフィードでは、ツイートをタップすると、そのタブ内のすべての返信を含む新しい画面が表示されます。これは、各タブ内に個別のナビゲーションスタックが存在すると考えることができます。React Navigationでモデル化する方法はまさにこれです。

import * as React from 'react';
import { Button, Text, View } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

function DetailsScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Details!</Text>
</View>
);
}

function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}

function SettingsScreen({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}

const HomeStack = createNativeStackNavigator();

function HomeStackScreen() {
return (
<HomeStack.Navigator>
<HomeStack.Screen name="Home" component={HomeScreen} />
<HomeStack.Screen name="Details" component={DetailsScreen} />
</HomeStack.Navigator>
);
}

const SettingsStack = createNativeStackNavigator();

function SettingsStackScreen() {
return (
<SettingsStack.Navigator>
<SettingsStack.Screen name="Settings" component={SettingsScreen} />
<SettingsStack.Screen name="Details" component={DetailsScreen} />
</SettingsStack.Navigator>
);
}

const Tab = createBottomTabNavigator();

export default function App() {
return (
<NavigationContainer>
<Tab.Navigator screenOptions={{ headerShown: false }}>
<Tab.Screen name="HomeStack" component={HomeStackScreen} />
<Tab.Screen name="SettingsStack" component={SettingsStackScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}

TabBarIOSまたは他のコンポーネントの代わりにTabNavigatorが必要なのはなぜですか?

アプリで使用しているナビゲーションライブラリに統合せずに、スタンドアロンのタブバーコンポーネントを使用しようとするのが一般的です。場合によっては、これで問題なく動作します。ただし、これを行うと、予期しない問題が発生してイライラする可能性があることに注意する必要があります。

たとえば、React NavigationのタブナビゲーターはAndroidのバックボタンの処理を自動的に行ってくれますが、スタンドアロンのコンポーネントは通常そうではありません。さらに、必要な場合に「このタブにジャンプしてからこの画面に移動する」などのアクションを実行する場合、2つの異なるAPIを呼び出す必要があるため、(開発者として)実行するのがより困難になります。最後に、モバイルユーザーインターフェイスには、特定のコンポーネントが他のコンポーネントのレイアウトまたは存在を認識する必要がある多数の小さな設計上の詳細があります。たとえば、半透明のタブバーがある場合、コンテンツはその下にスクロールする必要があり、スクロールビューには、コンテンツをすべて表示できるようにタブバーの高さと同じ下のインセットを設定する必要があります。タブバーをダブルタップすると、アクティブなナビゲーションスタックがスタックの最上部にポップし、もう一度行うと、そのスタックのアクティブなスクロールビューが最上部までスクロールする必要があります。これらの動作はすべてReact Navigationですぐに実装されるわけではありませんが、実装される予定であり、スタンドアロンのタブビューコンポーネントを使用すると、これらは何も得られません。

タブナビゲーターにはスタックが含まれており、特定の画面でタブバーを非表示にしたい

ドキュメントはこちらを参照してください