Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Вкладки

Вкладки (tabs) — панель внизу экрана, которая переключает главные разделы приложения. В блоге будет две вкладки: «Статьи» и «Профиль». Экран статьи при этом должен открываться поверх вкладок, со стрелкой «назад».

Структура файлов

Экраны вкладок кладут в папку-группу. Имя в круглых скобках, например (tabs), группирует файлы, но в адрес не входит: app/(tabs)/profile.tsx открывается по адресу /profile.

app/
├── _layout.tsx          корневой стек
├── (tabs)/
│   ├── _layout.tsx      панель вкладок
│   ├── index.tsx        вкладка «Статьи», адрес /
│   └── profile.tsx      вкладка «Профиль», адрес /profile
└── posts/
    └── [id].tsx         экран статьи поверх вкладок

Перенесите app/index.tsx в app/(tabs)/index.tsx и создайте экран профиля:

// app/(tabs)/profile.tsx
import { Text, View } from 'react-native';
 
export default function Profile() {
  return (
    <View style={{ flex: 1, padding: 16 }}>
      <Text style={{ fontSize: 18 }}>Анна, читатель с 2024 года</Text>
    </View>
  );
}

Макет вкладок

Создайте макет внутри группы:

// app/(tabs)/_layout.tsx
import { Ionicons } from '@expo/vector-icons';
import { Tabs } from 'expo-router';
 
export default function TabsLayout() {
  return (
    <Tabs screenOptions={{ tabBarActiveTintColor: '#2563eb' }}>
      <Tabs.Screen
        name="index"
        options={{
          title: 'Статьи',
          tabBarIcon: ({ color, size }) => <Ionicons name="newspaper" color={color} size={size} />,
        }}
      />
      <Tabs.Screen
        name="profile"
        options={{
          title: 'Профиль',
          tabBarIcon: ({ color, size }) => <Ionicons name="person" color={color} size={size} />,
        }}
      />
    </Tabs>
  );
}

Внизу экрана появятся две вкладки с иконками газеты и человека; активная подсвечена синим. tabBarIcon получает цвет и размер, подходящие текущему состоянию вкладки. Пакет иконок @expo/vector-icons уже есть в шаблоне.

Корневой стек

Группа вкладок становится одним экраном корневого стека. У вкладок своя шапка, поэтому шапку стека для них скрывают:

// app/_layout.tsx
import { Stack } from 'expo-router';
 
export default function RootLayout() {
  return (
    <Stack>
      <Stack.Screen name="(tabs)" options={{ headerShown: false }} />
      <Stack.Screen name="posts/[id]" options={{ title: 'Статья' }} />
    </Stack>
  );
}

Нажмите на статью во вкладке «Статьи» — её экран откроется поверх, панель вкладок скроется, а стрелка «назад» вернёт к списку. Ссылки в app/(tabs)/index.tsx менять не нужно: адрес /posts/[id] остался прежним.

Частая ошибка

Оставить и app/index.tsx, и app/(tabs)/index.tsx. Оба файла претендуют на адрес /, и Expo Router не может выбрать экран. Главный экран должен быть ровно в одном месте — после переноса старый файл удалите.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.