Tab навигатор
Возможно, наиболее распространенным стилем навигации в мобильных приложениях является навигация на основе вкладок. Это могут быть вкладки внизу экрана или вверху под заголовком (или даже вместо заголовка).
Это руководство охватывает createBottomTabNavigator. Вы также можете использовать createMaterialBottomTabNavigator и createMaterialTopTabNavigator для добавления вкладок в ваше приложение.
Прежде чем продолжить, сначала установите @react-navigation/bottom-tabs:
- npm
- Yarn
- pnpm
npm install @react-navigation/bottom-tabs@next
yarn add @react-navigation/bottom-tabs@next
pnpm add @react-navigation/bottom-tabs@next
Минимальный пример навигации по вкладкам
import * as React from 'react'
import { Text, View } from 'react-native'
import { NavigationContainer } from '@react-navigation/native'
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'
const HomeScreen = () => (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home!</Text>
</View>
)
const SettingsScreen = () => (
<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>
)
}
Попробуйте этот пример на Snack
Настройка внешнего вида
Это похоже на то, как вы настраиваете навигатор стека - некоторые свойства устанавливаются при инициализации навигатора вкладок, а другие можно настраивать для каждого экрана в параметрах.
// You can import Ionicons from @expo/vector-icons if you use Expo or
// react-native-vector-icons/Ionicons otherwise.
import * as React from 'react'
import { Text, View } from 'react-native'
import Ionicons from 'react-native-vector-icons/Ionicons'
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'
import { NavigationContainer } from '@react-navigation/native'
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
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'
}
// 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>
)
}
Попробуйте этот пример на Snack
Давайте разберем это:
tabBarIcon
- это поддерживаемая опция в нижнем навигаторе вкладок. Итак, мы знаем, что можем использовать его в наших компонентах экрана в propoptions
, но в этом случае мы решили поместить ее в propscreenOptions
вTab.Navigator
, чтобы централизовать конфигурацию значков для удобства.tabBarIcon
- это функция, которой задаются параметры состоянияfocused
,color
иsize
. Если вы посмотрите дальше в конфигурации, вы увидитеtabBarOptions
,activeTintColor
иinactiveTintColor
. По умолчанию используются значения по умолчанию для платформы iOS, но вы можете изменить их здесь. Цвет, который передается вtabBarIcon
, может быть активным или неактивным, в зависимости от состояния в фокусе (сфокусирован активен). Размер - это размер значка, ожидаемый панелью вкладок.Прочтите полный справочник по API для получения дополнительной информации о параметрах конфигурации
createBottomTabNavigator
.
Добавляйте значки к иконкам
Иногда мы хотим добавить значки к некоторым значкам. Для этого вы можете использовать параметр tabBarBadge
:
<Tab.Screen name="Home" component={HomeScreen} options={{ tabBarBadge: 3 }} />
Попробуйте этот пример на Snack
С точки зрения пользовательского интерфейса этот компонент готов к использованию, но вам все еще нужно найти способ правильно передать счетчик значков откуда-то еще, например, с помощью React Context, Redux, MobX или эмиттеров событий.
Переход между вкладками
Для переключения с одной вкладки на другую используется знакомый API - navigation.navigate
.
const HomeScreen = ({ navigation }) => {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home!</Text>
<Button
title="Go to Settings"
onPress={() => navigation.navigate('Settings')}
/>
</View>
)
}
const SettingsScreen = ({ navigation }) => {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings!</Text>
<Button title="Go to Home" onPress={() => navigation.navigate('Home')} />
</View>
)
}
Попробуйте этот пример на Snack
Навигатор стека для каждой вкладки
Обычно вкладки не просто отображают один экран - например, в своей ленте Twitter вы можете нажать на твит, и он приведет вас к новому экрану внутри этой вкладки со всеми ответами. Вы можете думать об этом как о наличии отдельных стеков навигации внутри каждой вкладки, и именно так мы будем моделировать их в React Navigation.
import * as React from 'react'
import { Button, Text, View } from 'react-native'
import { NavigationContainer } from '@react-navigation/native'
import { createStackNavigator } from '@react-navigation/stack'
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'
const DetailsScreen = () => {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Details!</Text>
</View>
)
}
const 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>
)
}
const 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 = createStackNavigator()
const HomeStackScreen = () => {
return (
<HomeStack.Navigator>
<HomeStack.Screen name="Home" component={HomeScreen} />
<HomeStack.Screen name="Details" component={DetailsScreen} />
</HomeStack.Navigator>
)
}
const SettingsStack = createStackNavigator()
const SettingsStackScreen = () => {
return (
<SettingsStack.Navigator>
<SettingsStack.Screen name="Settings" component={SettingsScreen} />
<SettingsStack.Screen name="Details" component={DetailsScreen} />
</SettingsStack.Navigator>
)
}
const Tab = createBottomTabNavigator();
const App = () => {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeStackScreen} />
<Tab.Screen name="Settings" component={SettingsStackScreen} />
</Tab.Navigator>
</NavigationContainer>
)
}
export default App
Попробуйте этот пример на Snack
Done
Чтобы узнать, насколько хорошо вы усвоили этот урок, пройдите тест в мобильном приложении нашей школы по этой теме или в боте Telegram.
Links
Contributors ✨
Thanks goes to these wonderful people (emoji key):
Dmitriy Vasilev 💲 |