JavaRush /Курсы /Модуль 3: React /Создание кастомных кнопок для навигации — настройка стиле...

Создание кастомных кнопок для навигации — настройка стилей и иконок

Модуль 3: React
22 уровень , 7 лекция
Открыта

Создание кастомной кнопки для Tab Navigation

По умолчанию React Navigation предоставляет базовый внешний вид вкладок (табов). Но давайте будем честными: они не всегда отражают стиль приложения, над которым мы работаем. В реальных проектах нужно добавить иконки, настроить цвета или даже заменить стандартные вкладки на уникальные компоненты. Это и будет нашей задачей.

Шаг 1: базовая настройка

Сначала создадим новый файл CustomTabBarButton.tsx, где мы будем хранить наш кастомный компонент.

// components/CustomTabBarButton.tsx

import React from 'react';
import { TouchableOpacity, Text, StyleSheet } from 'react-native';

interface CustomTabBarButtonProps {
  label: string; // Текст вкладки
  onPress: () => void; // Функция, которая срабатывает при нажатии
  isFocused: boolean; // Активна ли данная вкладка
}

const CustomTabBarButton: React.FC<CustomTabBarButtonProps> = ({ label, onPress, isFocused }) => {
  return (
    <TouchableOpacity
      style={[styles.container, isFocused && styles.focused]}
      onPress={onPress}
    >
      <Text style={[styles.label, isFocused && styles.labelFocused]}>
        {label}
      </Text>
    </TouchableOpacity>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    paddingVertical: 10,
    backgroundColor: '#fff', // Базовый цвет вкладки
  },
  focused: {
    backgroundColor: '#4CAF50', // Цвет, когда вкладка активна
  },
  label: {
    fontSize: 14,
    color: '#999', // Цвет текста по умолчанию
  },
  labelFocused: {
    color: '#fff', // Цвет текста, когда вкладка активна
  },
});

export default CustomTabBarButton;

Здесь мы используем TouchableOpacity для создания кнопки и добавляем стили для активного состояния вкладки с помощью пропса isFocused.

Шаг 2: подключение к Bottom Tab Navigation

Теперь подключим наш компонент CustomTabBarButton к Bottom Tab Navigation в App.tsx (или любом другом файле, где вы описали createBottomTabNavigator).

import React from 'react';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import ScreenA from './screens/ScreenA';
import ScreenB from './screens/ScreenB';
import CustomTabBarButton from './components/CustomTabBarButton';

const Tab = createBottomTabNavigator();

const App: React.FC = () => {
  return (
    <Tab.Navigator
            screenOptions={({ route }) => ({
        tabBarButton: (props) => (
          <CustomTabBarButton
            {...props}
            label={route.name}
            isFocused={props.accessibilityState?.selected || false}
          />
        ),
      })}
    >
      <Tab.Screen name="Home" component={ScreenA} />
      <Tab.Screen name="Settings" component={ScreenB} />
    </Tab.Navigator>
  );
};

export default App;

Разбор кода:

  • Мы передаём tabBarButton в screenOptions, чтобы заменить стандартную кнопку вкладки на наш кастомный компонент.
  • Передаём значение selected из props.accessibilityState для определения активного состояния вкладки.
  • Используем имя экрана route.name в качестве текста кнопки.

Шаг 3: добавление иконок в кнопки

Пустые кнопки — это скучно, согласны? Давайте добавим иконки. Для этого установим популярную библиотеку react-native-vector-icons.

npm install react-native-vector-icons

Теперь добавим иконки в кастомную кнопку:

// components/CustomTabBarButton.tsx

import React from 'react';
import { TouchableOpacity, Text, StyleSheet } from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome'; // Подключаем библиотеку иконок

interface CustomTabBarButtonProps {
  label: string;
  onPress: () => void;
  isFocused: boolean;
  iconName: string; // Новый пропс для имени иконки
}

const CustomTabBarButton: React.FC<CustomTabBarButtonProps> = ({ label, onPress, isFocused, iconName }) => {
  return (
    <TouchableOpacity
      style={[styles.container, isFocused && styles.focused]}
      onPress={onPress}
    >
      <Icon name={iconName} size={20} color={isFocused ? '#fff' : '#999'} />
      <Text style={[styles.label, isFocused && styles.labelFocused]}>
        {label}
      </Text>
    </TouchableOpacity>
  );
};

export default CustomTabBarButton;

Обновляем App.tsx:

Теперь передадим имя иконки для каждой вкладки:

<Tab.Navigator
  screenOptions={({ route }) => ({
    tabBarButton: (props) => (
      <CustomTabBarButton 
        {...props} 
        label={route.name} 
        isFocused={props.accessibilityState?.selected || false}
        iconName={route.name === 'Home' ? 'home' : 'cog'} // Иконки для экранов
      />
    ),
  })}
>
  <Tab.Screen name="Home" component={ScreenA} />
  <Tab.Screen name="Settings" component={ScreenB} />
</Tab.Navigator>

Теперь вместо скучных пустых кнопок у нас есть иконки, которые динамически меняются в зависимости от текущего экрана.

Создание кастомной кнопки для Drawer Navigation

Drawer Navigation часто используется для "скрытых" разделов, таких как настройки или информация о приложении. Мы создадим стилизованную кнопку для боковой панели.

Шаг 1: настройка кастомного контента для Drawer

Drawer Navigation поддерживает кастомизацию меню с помощью компонента drawerContent.

// App.tsx

import React from 'react';
import { createDrawerNavigator, DrawerContentScrollView, DrawerItem } from '@react-navigation/drawer';
import ScreenA from './screens/ScreenA';
import ScreenB from './screens/ScreenB';

const Drawer = createDrawerNavigator();

const CustomDrawerContent = (props) => {
  return (
    <DrawerContentScrollView {...props}>
      <DrawerItem
        label="Home"
        onPress={() => props.navigation.navigate('Home')}
        style={{ backgroundColor: '#4CAF50', borderRadius: 5 }}
        labelStyle={{ color: '#fff', fontWeight: 'bold' }}
      />
      <DrawerItem
        label="Settings"
        onPress={() => props.navigation.navigate('Settings')}
        style={{ backgroundColor: '#4CAF50', borderRadius: 5, marginTop: 10 }}
        labelStyle={{ color: '#fff', fontWeight: 'bold' }}
      />
    </DrawerContentScrollView>
  );
};

const App: React.FC = () => {
  return (
    <Drawer.Navigator drawerContent={(props) => <CustomDrawerContent {...props} />}>
      <Drawer.Screen name="Home" component={ScreenA} />
      <Drawer.Screen name="Settings" component={ScreenB} />
    </Drawer.Navigator>
    );
};

export default App;

Здесь мы заменяем стандартный контент боковой панели на кастомные элементы с помощью DrawerContentScrollView и DrawerItem. Это позволяет настроить внешний вид кнопок.

Обсуждение типичных ошибок

  1. Проблемы с библиотекой иконок. Если иконки не отображаются, убедитесь, что вы правильно установили react-native-vector-icons, а также проверили его интеграцию с проектом (особенно на Android).
  2. Передача параметров в кастомные кнопки. Всегда проверяйте типизацию, чтобы избежать ошибок при использовании пропсов.
  3. Неправильная стилизация. Если стили не применяются, убедитесь, что ваши кастомные кнопки наследуют правильные базовые стили от TouchableOpacity.
2
Задача
Модуль 3: React, 22 уровень, 7 лекция
Недоступна
Создание базовой кастомной кнопки для навигации
Создание базовой кастомной кнопки для навигации
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ