O repositório foi movido para https://github.com/react-navigation/react-navigation/tree/main/packages/react-native-tab-view. Abra problemas e puxe solicitações para lá.
Uma guia Plataforma cruzada Exibir componente para o React Native. Implementado usando react-native-pager-view no Android & iOS e PanResponder no Web, MacOS e Windows.
Para usar esta biblioteca, você precisa garantir que você esteja usando a versão correta do React Native. Se você estiver usando uma versão do React Native, que é inferior a 0.63 precisará atualizá -la antes de tentar usar esta biblioteca.
Versão react-native-tab-view | Versão nativa de reação necessária |
|---|---|
2.xx | < 0.63 |
3.xx | >= 0.63 |
Abra um terminal na raiz do projeto e execute:
yarn add react-native-tab-view Agora precisamos instalar react-native-pager-view se você planeja suportar iOS e Android.
Se você estiver usando a Expo, para garantir que obtenha as versões compatíveis das bibliotecas, execute:
expo install react-native-pager-viewSe você não estiver usando a Expo, execute o seguinte:
yarn add react-native-pager-viewTerminamos! Agora você pode criar e executar o aplicativo no seu dispositivo/simulador.
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 } }
/>
) ;
}Experimente este exemplo no lanche
O pacote exporta um componente TabView , que é o que você usaria para renderizar a visualização da guia e um componente TabBar , que é a implementação da barra de guia padrão.
TabViewComponente de contêiner responsável pela renderização e gerenciamento de guias. Segue os estilos de design de material por padrão.
Uso básico é assim:
< TabView
navigationState = { { index , routes } }
onIndexChange = { setIndex }
renderScene = { SceneMap ( {
first : FirstRoute ,
second : SecondRoute ,
} ) }
/> navigationState ( required )Estado para a visualização da guia. O estado deve conter as seguintes propriedades:
index : Um número representando o índice da rota ativa na matriz de routesroutes : Uma matriz contendo uma lista de objetos de rota usados para renderizar as guiasCada objeto de rota deve conter as seguintes propriedades:
key : Uma chave única para identificar a rota (necessária)title : Título para a rota para exibir na barra de guiasicon : Ícone para a rota exibir na barra de guiasaccessibilityLabel : rótulo de acessibilidade para o botão de guiatestID : ID de teste para o botão da guiaExemplo:
{
index : 1 ,
routes : [
{ key : 'music' , title : 'Music' } ,
{ key : 'albums' , title : 'Albums' } ,
{ key : 'recents' , title : 'Recents' } ,
{ key : 'purchased' , title : 'Purchased' } ,
]
} TabView é um componente controlado, o que significa que o index precisa ser atualizado através do retorno de chamada onIndexChange .
onIndexChange ( required )Retorno de chamada que é chamado na alteração da guia, recebe o índice da nova guia como argumento. O estado de navegação precisa ser atualizado quando é chamado, caso contrário, a alteração será descartada.
renderScene ( required )Retorno de chamada que retorna um elemento React para renderizar como a página para a guia. Recebe um objeto que contém a rota como argumento:
const renderScene = ( { route , jumpTo } ) => {
switch ( route . key ) {
case 'music' :
return < MusicRoute jumpTo = { jumpTo } /> ;
case 'albums' :
return < AlbumsRoute jumpTo = { jumpTo } /> ;
}
} ; Você precisa garantir que suas rotas individuais implementem um shouldComponentUpdate para melhorar o desempenho. Para facilitar a especificação dos componentes, você pode usar o ajudante de SceneMap .
SceneMap leva um objeto com o mapeamento do route.key para reagir componentes e retorna uma função a ser usada com renderScene Prop.
import { SceneMap } from 'react-native-tab-view' ;
...
const renderScene = SceneMap ( {
music : MusicRoute ,
albums : AlbumsRoute ,
} ) ; Especificar os componentes dessa maneira é mais fácil e cuida da implementação de um método shouldComponentUpdate .
Cada cena recebe os seguintes adereços:
route : a rota atual renderizada pelo componentejumpTo : método para pular para outras abas, segue uma route.keyposition : Nó animado que representa a posição atual O método jumpTo pode ser usado para navegar para outras guias programaticamente:
this . props . jumpTo ( 'albums' ) ; Todas as cenas renderizadas com SceneMap são otimizadas usando React.PureComponent e não renderizam quando os adereços ou estados dos pais mudarem. Se você precisar de mais controle sobre como suas cenas atualizam (por exemplo - desencadeando uma renderização, mesmo que o navigationState não tenha mudado), use renderScene diretamente em vez de usar SceneMap .
IMPORTANTE: Não passe funções em linha para SceneMap , por exemplo, não faça o seguinte:
SceneMap ( {
first : ( ) => < FirstRoute foo = { this . props . foo } /> ,
second : SecondRoute ,
} ) ;Sempre defina seus componentes em outros lugares no nível superior do arquivo. Se você passar funções em linha, ele recriará o componente a cada renderização, o que causará toda a rota para desmontar e remontar todas as alterações. É muito ruim para o desempenho e também fará com que qualquer estado local seja perdido.
Se você precisar passar adereços adicionais, use uma função renderScene personalizada:
const renderScene = ( { route } ) => {
switch ( route . key ) {
case 'first' :
return < FirstRoute foo = { this . props . foo } /> ;
case 'second' :
return < SecondRoute /> ;
default :
return null ;
}
} ; renderTabBarRetorno de chamada que retorna um elemento de reação personalizado a ser usado como barra de guia:
import { TabBar } from 'react-native-tab-view' ;
...
< TabView
renderTabBar = { props => < TabBar { ... props } /> }
. . .
/ >Se isso não for especificado, a barra de guia padrão será renderizada. Você passa por esses adereços para personalizar a barra de guias padrão, fornecer sua própria barra de guias ou desativar completamente a barra de guias.
< TabView
renderTabBar = { ( ) => null }
. . .
/ > tabBarPosition Posição da barra da guia na visualização da guia. Os valores possíveis são 'top' e 'bottom' . Padrões para 'top' .
lazyFunção que pega um objeto com a rota atual e retorna um booleano para indicar se deve renderizar preguiçosamente as cenas.
Por padrão, todas as cenas são renderizadas para proporcionar uma experiência de furto mais suave. Mas você pode adiar a renderização de cenas sem foco até que o usuário as veja. Para permitir a renderização preguiçosa para uma cena específica, true a getLazy para essa route :
< TabView
lazy = { ( { route } ) => route . name === 'Albums' }
. . .
/ > Quando você habilita a renderização preguiçosa para uma tela, geralmente leva algum tempo para renderizar quando entrar em foco. Você pode usar o suporte renderLazyPlaceholder para personalizar o que o usuário vê durante este curto período.
Você também pode passar por um booleano para permitir preguiçoso para todas as cenas:
< TabView
lazy
/> lazyPreloadDistance Quando lazy é ativado, você pode especificar quantas rotas adjacentes devem ser pré -carregadas com este suporte. Esse valor é padrão para 0 o que significa que as páginas preguiçosas são carregadas à medida que entram na visualização.
renderLazyPlaceholder O retorno de chamada que retorna um elemento de reação personalizado para renderizar rotas que ainda não foram renderizadas. Recebe um objeto que contém a rota como argumento. O suporte lazy também precisa ser ativado.
Essa visão geralmente é mostrada apenas por uma fração de segundo. Mantenha -o leve.
Por padrão, isso torna null .
keyboardDismissModeString indicando se o teclado é descartado em resposta a um gesto de arrasto. Valores possíveis são:
'auto' (padrão): o teclado é descartado quando o índice muda.'on-drag' : o teclado é descartado quando um arrasto começa.'none' : os arrastos não descartam o teclado. swipeEnabled Booleano indicando se deve permitir gestos de deslizamento. Os gestos de deslizamento são ativados por padrão. A passagem false desativará os gestos de deslizamento, mas o usuário ainda pode alternar as guias pressionando a barra de guias.
animationEnabledAtiva a animação ao alterar a guia. Por padrão, é verdade.
onSwipeStartO retorno de chamada que é chamado quando o gesto de deslizamento começa, ou seja, o usuário toca a tela e a move.
onSwipeEndRetorno de chamada que é chamado quando o gesto de deslizamento termina, ou seja, o usuário levanta o dedo da tela após o gesto do deslizamento.
initialLayoutObjeto que contém a altura e a largura inicial das telas. A passagem disso melhorará o desempenho inicial de renderização. Para a maioria dos aplicativos, este é um bom padrão:
< TabView
initialLayout = { { width : Dimensions . get ( 'window' ) . width } }
. . .
/ > sceneContainerStyleEstilo a ser aplicado à exibição em cada tela. Você pode passar por isso para substituir alguns estilos padrão, como recorte de transbordamento:
pagerStyleEstilo a ser aplicado à exibição do pager envolvendo todas as cenas.
styleEstilo a ser aplicado ao contêiner de exibição de guia.
TabBar Projeto de material Barra de guia Temática. Para personalizar a barra de guias, você precisará usar o suporte renderTabBar do TabView para renderizar o TabBar e passar adereços adicionais.
Por exemplo, para personalizar a cor do indicador e a cor do fundo da barra de guias, você pode passar indicatorStyle e os acessórios style para o TabBar , respectivamente:
const renderTabBar = props => (
< TabBar
{ ... props }
indicatorStyle = { { backgroundColor : 'white' } }
style = { { backgroundColor : 'pink' } }
/>
) ;
//...
return (
< TabView
renderTabBar = { renderTabBar }
. . .
/ >
);getLabelText Função que leva um objeto com a rota atual e retorna o texto da etiqueta para a guia. Usa route.title por padrão.
< TabBar
getLabelText = { ( { route } ) => route . title }
. . .
/ > getAccessible Função que leva um objeto com a rota atual e retorna um booleano para indicar se deve marcar uma guia como accessible . Padrões para true .
getAccessibilityLabel Função que pega um objeto com a rota atual e retorna um rótulo de acessibilidade para o botão da guia. Usa route.accessibilityLabel por padrão, se especificado, caso contrário, usa o título da rota.
< TabBar
getAccessibilityLabel = { ( { route } ) => route . accessibilityLabel }
. . .
/ > getTestID Função que pega um objeto com a rota atual e retorna um ID de teste para o botão da guia para localizar este botão de guia nos testes. Usa route.testID por padrão.
< TabBar
getTestID = { ( { route } ) => route . testID }
. . .
/ > renderIconFunção que leva um objeto com a rota atual, o status e a cor focada e retorna um elemento de reação personalizado a ser usado como um ícone.
< TabBar
renderIcon = { ( { route , focused , color } ) => (
< Icon
name = { focused ? 'albums' : 'albums-outlined' }
color = { color }
/>
) }
. . .
/ > renderLabelFunção que leva um objeto com a rota atual, o status e a cor focada e retorna um elemento de reação personalizado a ser usado como um rótulo.
< TabBar
renderLabel = { ( { route , focused , color } ) => (
< Text style = { { color , margin : 8 } } >
{ route . title }
</ Text >
) }
. . .
/ > renderTabBarItem Função que pega um objeto TabBarItemProps e retorna um elemento de reação personalizado a ser usado como um botão de guia.
renderIndicatorFunção que leva um objeto com a rota atual e retorna um elemento de reação personalizado a ser usado como um indicador de guia.
renderBadgeFunção que leva um objeto com a rota atual e retorna um elemento de reação personalizado a ser usado como um crachá.
onTabPressFunção para executar na guia pressione. Ele recebe a cena para a guia pressionada, útil para coisas como rolagem para cima.
Por padrão, a guia Pressione também alterna a guia. Para evitar esse comportamento, você pode ligar para preventDefault :
< TabBar
onTabPress = { ( { route , preventDefault } ) => {
if ( route . key === 'home' ) {
preventDefault ( ) ;
// Do something else
}
} }
. . .
/ > onTabLongPressFunção para executar na guia Pressione há muito tempo, use para coisas como mostrar um menu com mais opções
activeColorCor personalizada para ícone e etiqueta na guia ativa.
inactiveColorCor personalizada para ícone e etiqueta na guia inativa.
pressColorCor para o material Ripple (Android> = 5.0).
pressOpacityOpacidade para a guia pressionada (apenas iOS e Android <5,0).
scrollEnabledBooleano indicando se deve tornar a barra de guia rolável.
Se você definir scrollEnabled como true , também deverá especificar uma width no tabStyle para melhorar a renderização inicial.
bouncesBooleano indicando se a barra de guias salta ao rolar.
tabStyleEstilo para aplicar aos itens individuais da guia na barra de guias.
Por padrão, todos os itens da guia ocupam a mesma largura pré-calculada com base na largura do contêiner. Se você deseja que eles tenham a largura original, você pode especificar width: 'auto' no tabStyle .
indicatorStyleEstilo a ser aplicado ao indicador ativo.
indicatorContainerStyleEstilo a ser aplicado à exibição do contêiner para o indicador.
labelStyleEstilo a ser aplicado ao rótulo do item da guia.
contentContainerStyleEstilo a ser aplicado ao recipiente interno para guias.
styleEstilo a ser aplicado ao contêiner da barra de guias.
gapDefina um espaçamento entre as guias.
testIDID do teste para o tabbar. Pode ser usado para rolar a barra de guias em testes
Se você deseja integrar a visualização da guia com o sistema de navegação da React Navigation, por exemplo, deseja poder navegar para uma guia usando navigation.navigate etc., você pode usar as seguintes integrações oficiais:
Observe que algumas funcionalidades não estão disponíveis com a integração do React Navegion 4 devido às limitações na navegação react. Por exemplo, é possível alterar dinamicamente as guias renderizadas.
A função renderScene é chamada sempre que o índice mudar. Se a sua função renderScene for cara, é uma boa ideia mover cada rota para um componente separado se não depender do índice e usar shouldComponentUpdate ou React.memo .
Por exemplo, em vez de:
const renderScene = ( { route } ) => {
switch ( route . key ) {
case 'home' :
return (
< View style = { styles . page } >
< Avatar />
< NewsFeed />
</ View >
) ;
default :
return null ;
}
} ;Faça o seguinte:
const renderScene = ( { route } ) => {
switch ( route . key ) {
case 'home' :
return < HomeComponent /> ;
default :
return null ;
}
} ; Onde <HomeComponent /> é um PureComponent se você estiver usando componentes de classe:
export default class HomeComponent extends React . PureComponent {
render ( ) {
return (
< View style = { styles . page } >
< Avatar />
< NewsFeed />
</ View >
) ;
}
} Ou, embrulhado em React.memo se você estiver usando componentes de função:
function HomeComponent ( ) {
return (
< View style = { styles . page } >
< Avatar />
< NewsFeed />
</ View >
) ;
}
export default React . memo ( HomeComponent ) ;Precisamos medir a largura do contêiner e, portanto, precisamos esperar antes de renderizar alguns elementos na tela. Se você conhece a largura inicial antecipada, pode passar e não precisaremos esperar para medi -lo. Na maioria das vezes, é apenas a largura da janela.
Por exemplo, passe o seguinte initialLayout para TabView :
const initialLayout = {
height : 0 ,
width : Dimensions . get ( 'window' ) . width ,
} ;A visualização da guia ainda reagirá às alterações na dimensão e se ajustará de acordo para acomodar coisas como mudança de orientação.
Se você tem um grande número de rotas, especialmente as imagens, isso pode diminuir muito a animação. Em vez disso, você pode renderizar um número limitado de rotas.
Por exemplo, faça o seguinte para renderizar apenas 2 rotas de cada lado:
const renderScene = ( { route } ) => {
if ( Math . abs ( index - routes . indexOf ( route ) ) > 2 ) {
return < View /> ;
}
return < MySceneComponent route = { route } /> ;
} ; Nestar o TabView dentro de um vertical ScrollView desativará as otimizações nos componentes FlatList renderizados dentro do TabView . Portanto, evite fazê -lo, se possível.
lazy e renderLazyPlaceholder para renderizar rotas conforme necessário A opção lazy é desativada por padrão para fornecer uma experiência de comutação de guias mais suave, mas você pode ativá -lo e fornecer um componente de espaço reservado para uma melhor experiência de carregamento preguiçoso. A ativação lazy pode melhorar o desempenho inicial da carga, renderizando rotas apenas quando elas aparecem. Consulte a referência do suporte para obter mais detalhes.
Durante o desenvolvimento, você pode executar o aplicativo de exemplo para testar suas alterações.
Verifique se o seu código passa o TypeScript e o ESLint. Execute o seguinte para verificar:
yarn typescript
yarn lintPara corrigir erros de formatação, execute o seguinte:
yarn lint -- --fixLembre -se de adicionar testes para sua alteração, se possível.