React Native Tab View¶
React Native Tab View - это кроссплатформенный компонент Tab View для React Native, реализованный с использованием react-native-pager-view
на Android и iOS и PanResponder на Web, macOS и Windows.
По умолчанию он соответствует принципам материального дизайна, но вы можете использовать собственную пользовательскую панель вкладок или расположить ее внизу.
Данный пакет не интегрируется с React Navigation. Если вы хотите интегрировать представление вкладок с системой навигации React Navigation, например, отображать экраны в панели вкладок и иметь возможность переходить между ними с помощью navigation.navigate
и т.д., используйте вместо этого Material Top Tab Navigator.
Установка¶
Чтобы использовать этот пакет, откройте Терминал в корне проекта и выполните команду:
1 |
|
Далее установите react-native-pager-view
, если вы планируете поддерживать iOS и Android.
Если вы используете Expo, то для обеспечения совместимости версий библиотек выполните команду:
1 |
|
Если вы не используете Expo, выполните следующее:
1 |
|
Готово! Теперь вы можете собрать и запустить приложение на своем устройстве/симуляторе.
Быстрый старт¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
|
Попробуйте рассмотреть этот пример на Snack
Другие примеры на Snack¶
Справочник по API¶
Пакет экспортирует компонент TabView
, который используется для отображения вида вкладок, и компонент TabBar
, который является реализацией панели вкладок по умолчанию.
TabView
¶
Контейнерный компонент, отвечающий за отрисовку и управление вкладками. По умолчанию использует стили Material Design.
Базовое использование выглядит следующим образом:
1 2 3 4 5 6 7 8 |
|
Параметры TabView
:
navigationState
(required
)
Состояние для представления вкладки. Состояние должно содержать следующие свойства:
index
: число, представляющее индекс активного маршрута в массивеroutes
.routes
: массив, содержащий список объектов маршрутов, используемых для отображения вкладок.
Каждый объект маршрута должен содержать следующие свойства:
key
: уникальный ключ для идентификации маршрута (обязательно)title
: заголовок маршрута для отображения на панели вкладокicon
: иконка маршрута для отображения на панели вкладокaccessibilityLabel
: метка доступности для кнопки вкладкиtestID
: идентификатор теста для кнопки вкладки
Пример:
1 2 3 4 5 6 7 8 9 |
|
TabView
является управляемым компонентом, а значит, index
должен обновляться через обратный вызов onIndexChange
.
onIndexChange
(required
)
Обратный вызов, который вызывается при смене вкладки и получает в качестве аргумента индекс новой вкладки.
При его вызове состояние навигации должно быть обновлено, иначе изменение будет отменено.
renderScene
(required
)
Обратный вызов, который возвращает элемент react для рендеринга в качестве страницы вкладки. В качестве аргумента получает объект, содержащий маршрут:
1 2 3 4 5 6 7 8 |
|
Для повышения производительности необходимо убедиться в том, что отдельные маршруты реализуют shouldComponentUpdate
. Для упрощения задания компонентов можно использовать помощник SceneMap
.
SceneMap
принимает объект с отображением route.key
на компоненты React и возвращает функцию для использования в свойстве renderScene
.
1 2 3 4 5 6 7 8 |
|
Такое задание компонентов проще и позволяет обойтись без реализации метода shouldComponentUpdate
.
Каждая сцена получает следующие реквизиты:
route
: текущий маршрут, отображаемый компонентомjumpTo
: метод для перехода на другие вкладки, в качестве аргумента принимаетroute.key
.position
: анимированный узел, представляющий текущую позицию
Метод jumpTo
может быть использован для программного перехода на другие вкладки:
1 |
|
Все сцены, отрисованные с помощью SceneMap
, оптимизированы с использованием React.PureComponent
и не перерисовываются при изменении реквизитов или состояний родителя. Если вам нужен больший контроль над обновлением сцен (например, инициирование повторного рендеринга, даже если navigationState
не изменилось), используйте renderScene
напрямую, а не с помощью SceneMap
.
ВАЖНО: Не передавайте в SceneMap
инлайн-функции, например, не делайте следующее:
1 2 3 4 |
|
Всегда определяйте свои компоненты в другом месте на верхнем уровне файла. Если вы передаете inline-функции, то при каждом рендеринге компонент будет создаваться заново, что приведет к размонтированию и повторному монтированию всего маршрута при каждом изменении. Это очень плохо сказывается на производительности, а также приводит к потере всех локальных состояний.
Если необходимо передать дополнительные реквизиты, используйте пользовательскую функцию renderScene
:
1 2 3 4 5 6 7 8 9 10 |
|
renderTabBar
Обратный вызов, который возвращает пользовательский элемент React Element для использования в качестве панели вкладок:
1 2 3 4 5 6 7 8 |
|
Если этот реквизит не указан, то отображается панель вкладок по умолчанию. Передавая этот реквизит, можно настроить панель вкладок по умолчанию, создать свою собственную панель вкладок или полностью отключить панель вкладок.
1 2 3 4 |
|
tabBarPosition
Положение панели вкладок в представлении вкладок. Возможные значения: top
и bottom
. По умолчанию принимается значение top
.
lazy
Функция принимает объект с текущим маршрутом и возвращает булево значение, указывающее, нужно ли лениво отрисовывать сцены.
По умолчанию все сцены отображаются, чтобы обеспечить более плавное пролистывание. Однако вы можете захотеть отложить отрисовку несфокусированных сцен до тех пор, пока пользователь не увидит их. Чтобы включить ленивый рендеринг для конкретной сцены, верните true
из getLazy
для этого route
:
1 2 3 4 |
|
Когда вы включаете ленивый рендеринг для экрана, обычно требуется некоторое время для рендеринга, когда он оказывается в фокусе. Вы можете использовать параметр renderLazyPlaceholder
для настройки того, что пользователь видит в течение этого короткого периода.
Можно также передать булево значение, чтобы включить ленивый рендеринг для всех сцен:
1 |
|
lazyPreloadDistance
Когда lazy
включен, можно указать, сколько соседних маршрутов должно быть предварительно загружено с помощью данного параметра. По умолчанию это значение равно 0
, что означает, что ленивые страницы загружаются по мере их попадания в область просмотра.
renderLazyPlaceholder
Обратный вызов, возвращающий пользовательский React-элемент для отрисовки маршрутов, которые еще не были отрисованы. В качестве аргумента получает объект, содержащий маршрут. Также необходимо включить параметр lazy
.
Это представление обычно показывается только на долю секунды. Необходимо поддерживать его легковесным.
По умолчанию отображается null
.
keyboardDismissMode
Строка, указывающая, будет ли клавиатура отключаться в ответ на жест перетаскивания. Возможные значения:
'auto'
(по умолчанию): клавиатура отключается при изменении индекса.'on-drag'
: клавиатура отключается, когда начинается перетаскивание.'none'
: перетаскивание не приводит к отключению клавиатуры.
swipeEnabled
Булево значение, указывающее, следует ли включить жесты пролистывания. По умолчанию жесты пролистывания включены. Если передать false
, то жесты пролистывания будут отключены, но пользователь по-прежнему сможет переключать вкладки, нажимая на панель вкладок.
animationEnabled
Включает анимацию при смене вкладки. По умолчанию это значение равно true
.
onSwipeStart
Обратный вызов, который вызывается, когда начинается жест смахивания, т.е. пользователь касается экрана и перемещает его.
onSwipeEnd
Обратный вызов, который вызывается, когда жест смахивания заканчивается, т.е. пользователь убирает палец с экрана после жеста смахивания.
initialLayout
Объект, содержащий начальную высоту и ширину экранов. Передача этого параметра позволит повысить производительность начального рендеринга. Для большинства приложений это хорошее значение по умолчанию:
1 2 3 4 5 6 |
|
overScrollMode
Используется для переопределения значения по умолчанию режима прокрутки пейджера. Может иметь значение auto
, always
или never
(только для Android).
sceneContainerStyle
Стиль, применяемый к представлению, оборачивающему каждый экран. Его можно передать, чтобы отменить некоторые стили по умолчанию, например, обрезание переполнения:
pagerStyle
Стиль, который будет применяться к представлению пейджера, оборачивающему все сцены.
style
Стиль, применяемый к контейнеру представления вкладки.
TabBar
¶
Тематическая панель вкладок в стиле Material Design. Для настройки панели вкладок необходимо использовать свойство renderTabBar
функции TabView
для рендеринга TabBar
и передать дополнительные реквизиты.
Например, чтобы настроить цвет индикатора и цвет фона панели вкладок, можно передать реквизиты indicatorStyle
и style
в TabBar
соответственно:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
Параметры TabBar
:
getLabelText
Функция, принимающая объект с текущим маршрутом и возвращающая текст метки для вкладки. По умолчанию используется route.title
.
1 2 3 4 |
|
getAccessible
Функция принимает объект с текущим маршрутом и возвращает логическое значение, указывающее, следует ли пометить вкладку как accessible
. По умолчанию принимает значение true
.
getAccessibilityLabel
Функция, принимающая объект с текущим маршрутом и возвращающая метку доступности для кнопки вкладки. По умолчанию используется route.accessibilityLabel
, если он указан, в противном случае используется заголовок маршрута.
1 2 3 4 5 6 |
|
getTestID
Функция, принимающая объект с текущим маршрутом и возвращающая тестовый идентификатор кнопки вкладки для определения местоположения этой кнопки в тестах. По умолчанию используется route.testID
.
1 2 3 4 |
|
renderIcon
Функция принимает объект с текущим маршрутом, сфокусированным статусом и цветом и возвращает пользовательский React-элемент для использования в качестве иконки.
1 2 3 4 5 6 7 8 9 |
|
renderLabel
Функция принимает объект с текущим маршрутом, сфокусированным статусом и цветом и возвращает пользовательский React-элемент для использования в качестве метки.
1 2 3 4 5 6 7 8 |
|
renderTabBarItem
Функция, принимающая объект TabBarItemProps
и возвращающая пользовательский React-элемент, который будет использоваться в качестве кнопки вкладки.
renderIndicator
Функция, которая принимает объект с текущим маршрутом и возвращает пользовательский React-элемент для использования в качестве индикатора вкладки.
renderBadge
Функция, которая принимает объект с текущим маршрутом и возвращает пользовательский React-элемент для использования в качестве бейджа.
onTabPress
Функция, выполняемая при нажатии на вкладку. Она получает сцену для нажатой вкладки, что полезно для таких вещей, как прокрутка к верху.
По умолчанию нажатие вкладки также переключает вкладку. Чтобы предотвратить такое поведение, можно вызвать функцию preventDefault
:
1 2 3 4 5 6 7 8 9 10 |
|
onTabLongPress
Функция, выполняемая при длительном нажатии на вкладку, используется для отображения меню с дополнительными опциями
activeColor
Пользовательский цвет для иконки и ярлыка на активной вкладке.
inactiveColor
Пользовательский цвет для иконки и ярлыка неактивной вкладки.
pressColor
Цвет для пульсации материала (только для Android >= 5.0).
pressOpacity
Непрозрачность для вкладки с нажатой кнопкой (только для iOS и Android < 5.0).
scrollEnabled
Булево значение, указывающее, следует ли сделать панель вкладок прокручиваемой.
При установке scrollEnabled
в true
следует также указать width
в tabStyle
для улучшения начального рендеринга.
bounces
Булево значение, указывающее, отскакивает ли панель вкладок при прокрутке.
tabStyle
Стиль, применяемый к отдельным элементам вкладки на панели вкладок.
По умолчанию все элементы вкладки занимают одну и ту же предварительно рассчитанную ширину, основанную на ширине контейнера. Если вы хотите, чтобы они имели свою первоначальную ширину, то можете указать width: 'auto'
в tabStyle
.
indicatorStyle
Стиль, применяемый к активному индикатору.
indicatorContainerStyle
Стиль, применяемый к представлению контейнера для индикатора.
labelStyle
Стиль, применяемый к метке элемента вкладки.
ContentContainerStyle
Стиль, применяемый к внутреннему контейнеру для вкладок.
style
(TabBar
)
Стиль, применяемый к контейнеру панели вкладок.
gap
Определяет расстояние между вкладками.
testID
Тестовый идентификатор для панели вкладок. Может использоваться для прокрутки панели вкладок в тестах
Советы по оптимизации¶
Избегайте ненужных повторных рендеров¶
Функция renderScene
вызывается каждый раз при изменении индекса. Если функция renderScene
является дорогостоящей, то для предотвращения ненужных повторных рендеров целесообразно переместить каждый маршрут в отдельный компонент, если он не зависит от индекса, и использовать shouldComponentUpdate
или React.memo
в компонентах маршрута.
Например, вместо:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Выполните следующие действия:
1 2 3 4 5 6 7 8 |
|
Где <HomeComponent />
- это PureComponent
, если вы используете компоненты класса:
1 2 3 4 5 6 7 8 9 10 |
|
Или обернуть в React.memo
, если вы используете функциональные компоненты:
1 2 3 4 5 6 7 8 9 10 |
|
Избежать задержки на один кадр¶
Нам необходимо измерить ширину контейнера и, следовательно, подождать перед выводом некоторых элементов на экран. Если вы заранее знаете начальную ширину, то можете передать ее, и нам не нужно будет ждать ее измерения. Чаще всего это просто ширина окна.
Например, передадим initialLayout
в TabView
:
1 2 3 4 |
|
Вид вкладки по-прежнему будет реагировать на изменения размеров и соответствующим образом подстраиваться под такие вещи, как изменение ориентации.
Оптимизация большого количества маршрутов¶
Если у вас большое количество маршрутов, особенно изображений, это может сильно замедлить анимацию. Вместо этого можно отрисовывать ограниченное число маршрутов.
Например, чтобы отобразить только 2 маршрута с каждой стороны, сделайте следующее:
1 2 3 4 5 6 7 |
|
Избегайте рендеринга TabView внутри ScrollView¶
Вложение TabView
внутри вертикального ScrollView
приведет к отключению оптимизаций в компонентах FlatList
, отрисованных внутри TabView
. Поэтому по возможности избегайте этого.
Используйте реквизиты lazy
и renderLazyPlaceholder
для рендеринга маршрутов по мере необходимости¶
Опция lazy
отключена по умолчанию для обеспечения более плавного переключения вкладок, но вы можете включить ее и предоставить компонент-плейсхолдер для лучшей работы с ленивой загрузкой. Включение lazy
может повысить производительность начальной загрузки за счет отрисовки маршрутов только при их появлении.