Репо был перенесен на https://github.com/react-navigation/react-navigation/tree/main/packages/react-native-tab-view. Пожалуйста, откройте проблемы и вытащите запросы там.
Кроссплатформенный компонент вкладки для React Native. Реализовано с использованием react-native-pager-view на Android & IOS и PanResponder в Интернете, MacOS и Windows.
Чтобы использовать эту библиотеку, вам необходимо убедиться, что вы используете правильную версию React Native. Если вы используете версию RACE Native, которая ниже 0.63 вам нужно будет обновить ее, прежде чем попытаться использовать эту библиотеку.
react-native-tab-view версии | Требуемая версия React Native |
|---|---|
2.xx | < 0.63 |
3.xx | >= 0.63 |
Откройте терминал в корне проекта и запустите:
yarn add react-native-tab-view Теперь нам нужно установить react-native-pager-view если вы планируете поддержать iOS и Android.
Если вы используете Expo, чтобы убедиться, что вы получаете совместимые версии библиотек, запустите:
expo install react-native-pager-viewЕсли вы не используете Expo, запустите следующее:
yarn add react-native-pager-viewМы закончили! Теперь вы можете создать и запустить приложение на своем устройстве/симуляторе.
import * as React from 'react' ;
import { View , useWindowDimensions } from 'react-native' ;
import { TabView , SceneMap } from 'react-native-tab-view' ;
const FirstRoute = ( ) => (
< View style = { { flex : 1 , backgroundColor : '#ff4081' } } />
) ;
const SecondRoute = ( ) => (
< View style = { { flex : 1 , backgroundColor : '#673ab7' } } />
) ;
const renderScene = SceneMap ( {
first : FirstRoute ,
second : SecondRoute ,
} ) ;
export default function TabViewExample ( ) {
const layout = useWindowDimensions ( ) ;
const [ index , setIndex ] = React . useState ( 0 ) ;
const [ routes ] = React . useState ( [
{ key : 'first' , title : 'First' } ,
{ key : 'second' , title : 'Second' } ,
] ) ;
return (
< TabView
navigationState = { { index , routes } }
renderScene = { renderScene }
onIndexChange = { setIndex }
initialLayout = { { width : layout . width } }
/>
) ;
}Попробуйте этот пример на закусок
Пакет экспортирует компонент TabView , который вы бы использовали для визуализации вкладок, и компонент TabBar , который является реализацией строки вкладок по умолчанию.
TabViewКомпонент контейнера, ответственный за рендеринг и управление вкладками. Следует за стилями дизайна материала по умолчанию.
Основное использование выглядит так:
< TabView
navigationState = { { index , routes } }
onIndexChange = { setIndex }
renderScene = { SceneMap ( {
first : FirstRoute ,
second : SecondRoute ,
} ) }
/> navigationState ( required )Установите представление в таблице. Государство должно содержать следующие свойства:
index : число, представляющее индекс активного маршрута в массиве routesroutes : массив, содержащий список объектов маршрута, используемых для рендеринга вкладокКаждый объект маршрута должен содержать следующие свойства:
key : уникальный ключ для определения маршрута (требуется)title : заголовок для маршрута для отображения в панели вкладокicon : значок маршрута для отображения в панели вкладокaccessibilityLabeltestID : идентификатор тестирования для кнопки вкладкиПример:
{
index : 1 ,
routes : [
{ key : 'music' , title : 'Music' } ,
{ key : 'albums' , title : 'Albums' } ,
{ key : 'recents' , title : 'Recents' } ,
{ key : 'purchased' , title : 'Purchased' } ,
]
} TabView - это контролируемый компонент, что означает, что index должен быть обновлен с помощью обратного вызова onIndexChange .
onIndexChange ( required )Обратный вызов, который вызывает изменение вкладки, получает индекс новой вкладки в качестве аргумента. Состояние навигации необходимо обновлять при его вызове, в противном случае изменение отбрасывается.
renderScene ( required )Обратный вызов, который возвращает элемент реагирования в рендеринг в качестве страницы для вкладки. Получает объект, содержащий маршрут в качестве аргумента:
const renderScene = ( { route , jumpTo } ) => {
switch ( route . key ) {
case 'music' :
return < MusicRoute jumpTo = { jumpTo } /> ;
case 'albums' :
return < AlbumsRoute jumpTo = { jumpTo } /> ;
}
} ; Вы должны убедиться, что ваши индивидуальные маршруты реализуют shouldComponentUpdate для повышения производительности. Чтобы упростить указание компонентов, вы можете использовать помощника SceneMap .
SceneMap берет объект renderScene отображением route.key .
import { SceneMap } from 'react-native-tab-view' ;
...
const renderScene = SceneMap ( {
music : MusicRoute ,
albums : AlbumsRoute ,
} ) ; Указание компонентов таким образом проще и заботится о реализации метода shouldComponentUpdate .
Каждая сцена получает следующий реквизит:
route : текущий маршрут, отображаемый компонентомjumpTo : метод прыгать на другие вкладки, берет route.keyposition : анимированный узел, который представляет текущую позицию Метод jumpTo может использоваться для программного перемещения к другим вкладкам:
this . props . jumpTo ( 'albums' ) ; Все сцены, отображаемые со SceneMap оптимизируются с использованием React.PureComponent и не повторно рендеринг, когда реквизит или состояния родителей изменяются. Если вам нужно больше контроля над тем, как обновляются ваши сцены (например, запуска повторного рендеринга, даже если navigationState не изменилась), используйте renderScene напрямую вместо использования SceneMap .
ВАЖНО: Например, не проходите встроенные функции в SceneMap : не делайте следующее:
SceneMap ( {
first : ( ) => < FirstRoute foo = { this . props . foo } /> ,
second : SecondRoute ,
} ) ;Всегда определяйте свои компоненты в другом месте на верхнем уровне файла. Если вы выполняете встроенные функции, это воссоздает компонент каждый рендеринг, что приведет к тому, что весь маршрут будет отступить и снять каждое изменение. Это очень плохо для производительности, а также приведет к потерянию любого местного штата.
Если вам нужно передать дополнительные реквизиты, используйте пользовательскую функцию renderScene :
const renderScene = ( { route } ) => {
switch ( route . key ) {
case 'first' :
return < FirstRoute foo = { this . props . foo } /> ;
case 'second' :
return < SecondRoute /> ;
default :
return null ;
}
} ; renderTabBarОбратный вызов, который возвращает пользовательский элемент React для использования в качестве панели вкладок:
import { TabBar } from 'react-native-tab-view' ;
...
< TabView
renderTabBar = { props => < TabBar { ... props } /> }
. . .
/ >Если это не указано, отображается строка вкладок по умолчанию. Вы передаете это реквизит, чтобы настроить панель вкладок по умолчанию, предоставить свою собственную панель вкладок или полностью отключить панель вкладок.
< TabView
renderTabBar = { ( ) => null }
. . .
/ > tabBarPosition Положение панели вкладок в представлении TAB. Возможные значения - 'top' и 'bottom' . По умолчанию 'top' .
lazyФункция, которая берет объект с текущим маршрутом и возвращает логический, чтобы указать, лениво отображать сцены.
По умолчанию все сцены представлены для обеспечения более плавного опыта. Но вы можете захотеть отложить рендеринг сфокусированных сцен, пока пользователь не увидит их. Чтобы включить ленивый рендеринг для конкретной сцены, вернитесь true от getLazy для этого route :
< TabView
lazy = { ( { route } ) => route . name === 'Albums' }
. . .
/ > Когда вы включите ленивый рендеринг для экрана, обычно требуется некоторое время, когда он попадает в фокус. Вы можете использовать предложение renderLazyPlaceholder , чтобы настроить то, что пользователь видит в течение этого короткого периода.
Вы также можете пройти логический, чтобы лениться для всех сцен:
< TabView
lazy
/> lazyPreloadDistance Когда lazy включена, вы можете указать, сколько соседних маршрутов следует предварительно загрузить с этой опорой. Это значение по умолчанию по умолчанию 0 , что означает, что ленивые страницы загружаются, когда они попадают в просмотр.
renderLazyPlaceholder Обратный вызов, который возвращает пользовательский элемент реагирования для рендеринга для маршрутов, которые еще не были отображаются. Получает объект, содержащий маршрут в качестве аргумента. lazy Prop также должна быть включена.
Эта точка зрения обычно показана только в течение секунды. Держите это легким.
По умолчанию это делает null .
keyboardDismissModeСтрока, указывающая, уворачивается ли клавиатура в ответ на жест перетаскивания. Возможные значения:
'auto' (по умолчанию): клавиатура отклоняется при изменении индекса.'on-drag' : клавиатура уворачивается, когда начинается сопротивление.'none' : перетаскивает, не отклоняют клавиатуру. swipeEnabled Логин, указывающий, включить ли жесты смахивания. Свигай жесты включены по умолчанию. Передача false отключит жесты, но пользователь все еще может переключать вкладки, нажав панель вкладок.
animationEnabledВключает анимацию при изменении вкладки. По умолчанию это правда.
onSwipeStartОбратный вызов, который вызывается, когда начинается жест промахи, то есть пользователь касается экрана и перемещает его.
onSwipeEndОбратный вызов, который вызывается, когда заканчивается жест промахи, то есть пользователь поднимает палец с экрана после жеста.
initialLayoutОбъект, содержащий начальную высоту и ширину экранов. Прохождение этого улучшит первоначальную производительность рендеринга. Для большинства приложений это хороший дефолт:
< TabView
initialLayout = { { width : Dimensions . get ( 'window' ) . width } }
. . .
/ > sceneContainerStyleСтиль, чтобы применить к визу, обертывая каждый экран. Вы можете передать это, чтобы переопределить некоторые стили по умолчанию, такие как переполнение обрезки:
pagerStyleСтиль, чтобы применить к пейджеру, обернуть все сцены.
styleСтиль, чтобы применить к контейнеру для просмотра вкладки.
TabBar Материал дизайн тематическая вкладка. Чтобы настроить панель вкладок, вам необходимо использовать Prop renderTabBar of TabView , чтобы отобразить TabBar и передать дополнительные реквизиты.
Например, чтобы настроить цвет индикатора и цвет фона стержней, вы можете передать indicatorStyle и style реквизита в TabBar соответственно:
const renderTabBar = props => (
< TabBar
{ ... props }
indicatorStyle = { { backgroundColor : 'white' } }
style = { { backgroundColor : 'pink' } }
/>
) ;
//...
return (
< TabView
renderTabBar = { renderTabBar }
. . .
/ >
);getLabelText Функция, которая берет объект с текущим маршрутом и возвращает текст метки для вкладки. Использует route.title по умолчанию.
< TabBar
getLabelText = { ( { route } ) => route . title }
. . .
/ > getAccessible Функция, которая берет объект с текущим маршрутом и возвращает логическое, чтобы указать, стоит ли отмечать вкладку как accessible . По умолчанию к true .
getAccessibilityLabel Функция, которая берет объект с текущим маршрутом и возвращает метку доступности для кнопки вкладки. Использует route.accessibilityLabel по умолчанию, если указано, в противном случае использует заголовок маршрута.
< TabBar
getAccessibilityLabel = { ( { route } ) => route . accessibilityLabel }
. . .
/ > getTestID Функция, которая берет объект с текущим маршрутом, и возвращает тестовый идентификатор для кнопки вкладки, чтобы найти эту кнопку вкладки в тестах. Использует route.testID по умолчанию.
< TabBar
getTestID = { ( { route } ) => route . testID }
. . .
/ > renderIconФункция, которая принимает объект с текущим маршрутом, сфокусированным состоянием и цветом и возвращает пользовательский элемент реагирования, который будет использоваться в качестве значка.
< TabBar
renderIcon = { ( { route , focused , color } ) => (
< Icon
name = { focused ? 'albums' : 'albums-outlined' }
color = { color }
/>
) }
. . .
/ > renderLabelФункция, которая принимает объект с текущим маршрутом, сфокусированным состоянием и цветом и возвращает пользовательский элемент реагирования, который будет использоваться в качестве метки.
< TabBar
renderLabel = { ( { route , focused , color } ) => (
< Text style = { { color , margin : 8 } } >
{ route . title }
</ Text >
) }
. . .
/ > renderTabBarItem Функция, которая принимает объект TabBarItemProps и возвращает пользовательский элемент React, который будет использоваться в качестве кнопки вкладки.
renderIndicatorФункция, которая берет объект с текущим маршрутом и возвращает пользовательский элемент реагирования, который будет использоваться в качестве индикатора вкладки.
renderBadgeФункция, которая берет объект с текущим маршрутом и возвращает пользовательский элемент реагирования, который будет использоваться в качестве значка.
onTabPressФункция для выполнения на вкладке нажмите. Он получает сцену для нажатой вкладки, полезной для таких вещей, как Scroll вверх.
По умолчанию нажатие вкладки также переключает вкладку. Чтобы предотвратить такое поведение, вы можете позвонить preventDefault :
< TabBar
onTabPress = { ( { route , preventDefault } ) => {
if ( route . key === 'home' ) {
preventDefault ( ) ;
// Do something else
}
} }
. . .
/ > onTabLongPressФункция для выполнения на вкладке Long Нажмите, используйте для того, чтобы показать меню с большим количеством параметров
activeColorПользовательский цвет для значков и метки на вкладке Active.
inactiveColorПользовательский цвет для значка и метки на вкладке «Неактивная».
pressColorЦвет для материала Ripple (только Android> = 5,0).
pressOpacityНепрозрачность для нажатой вкладки (iOS и Android <5.0).
scrollEnabledЛогический, указывающий, закрепить ли вкладок.
Если вы установите scrollEnabled true , вы также должны указать width в tabStyle , чтобы улучшить начальный рендеринг.
bouncesБулево, указывая, подпрыгивает ли вкладка при прокрутке.
tabStyleСтиль, чтобы применить к отдельным элементам вкладок в панели вкладок.
По умолчанию все элементы вкладок занимают одинаковую предварительную ширину на основе ширины контейнера. Если вы хотите, чтобы они взяли свою исходную ширину, вы можете указать width: 'auto' в tabStyle .
indicatorStyleСтиль, чтобы применить к активному индикатору.
indicatorContainerStyleСтиль, чтобы применить к представлению контейнера для индикатора.
labelStyleСтиль, чтобы применить к метке элемента вкладки.
contentContainerStyleСтиль, чтобы применить к внутреннему контейнеру для вкладок.
styleСтиль, чтобы применить к контейнеру для стержня.
gapОпределите интервал между вкладками.
testIDТест идентификатор для таббара. Можно использовать для прокрутки панели вкладок в тестах
Если вы хотите интегрировать представление TAB с навигационной системой React Navigation, например, хотите иметь возможность перейти на вкладку, используя navigation.navigate и т. Д., Вы можете использовать следующие официальные интеграции:
Обратите внимание, что некоторые функциональные возможности не доступны с интеграцией React Navigation 4 из -за ограничений в навигации React. Например, можно динамически изменить визуализированные вкладки.
Функция renderScene вызывается каждый раз, когда изменяется индекс. Если ваша функция renderScene стоит дорогой, это хорошая идея перемещать каждый маршрут к отдельному компоненту, если они не зависят от индекса, и использование shouldComponentUpdate или React.memo Мемо в компонентах вашего маршрута для предотвращения ненужных повторных ресурсов.
Например, вместо:
const renderScene = ( { route } ) => {
switch ( route . key ) {
case 'home' :
return (
< View style = { styles . page } >
< Avatar />
< NewsFeed />
</ View >
) ;
default :
return null ;
}
} ;Сделайте следующее:
const renderScene = ( { route } ) => {
switch ( route . key ) {
case 'home' :
return < HomeComponent /> ;
default :
return null ;
}
} ; Где <HomeComponent /> является PureComponent , если вы используете компоненты класса:
export default class HomeComponent extends React . PureComponent {
render ( ) {
return (
< View style = { styles . page } >
< Avatar />
< NewsFeed />
</ View >
) ;
}
} Или, завернут в React.memo , если вы используете функциональные компоненты:
function HomeComponent ( ) {
return (
< View style = { styles . page } >
< Avatar />
< NewsFeed />
</ View >
) ;
}
export default React . memo ( HomeComponent ) ;Нам нужно измерить ширину контейнера и, следовательно, нужно подождать, прежде чем рендерировать некоторые элементы на экране. Если вы знаете начальную ширину заранее, вы можете передать ее, и нам не нужно будет ждать ее измерения. Большую часть времени это всего лишь ширина окна.
Например, передайте следующий initialLayout to TabView :
const initialLayout = {
height : 0 ,
width : Dimensions . get ( 'window' ) . width ,
} ;Просмотр вкладки все равно будет реагировать на изменения в измерении и соответствующим образом адаптируется, чтобы приспособить такие вещи, как изменение ориентации.
Если вы большое количество маршрутов, особенно изображений, это может сильно замедлить анимацию. Вместо этого вы можете отображать ограниченное количество маршрутов.
Например, сделайте следующее, чтобы отобразить только 2 маршрута с каждой стороны:
const renderScene = ( { route } ) => {
if ( Math . abs ( index - routes . indexOf ( route ) ) > 2 ) {
return < View /> ;
}
return < MySceneComponent route = { route } /> ;
} ; Гнездование TabView внутри вертикального ScrollView отключит оптимизацию в компонентах FlatList , отображаемых внутри TabView . Так что избегайте этого, если это возможно.
lazy и renderLazyPlaceholder Reps для рендеринга по мере необходимости. lazy Option отключен по умолчанию, чтобы предоставить более плавный опыт переключения вкладок, но вы можете включить его и предоставить компонент заполнителей для лучшего ленивого опыта загрузки. Включение lazy может улучшить начальную производительность нагрузки путем рендеринга маршрутов только тогда, когда они появляются. См. Подробную информацию.
Во время разработки вы можете запустить пример примера для проверки ваших изменений.
Убедитесь, что ваш код проходит TypeScript и Eslint. Запустите следующее, чтобы проверить:
yarn typescript
yarn lintЧтобы исправить ошибки форматирования, запустите следующее:
yarn lint -- --fixНе забудьте добавить тесты для вашего изменения, если это возможно.