Das Repo wurde auf https://github.com/react-navigation/react-navigation/tree/main/packages/react-native-tab-view verschoben. Bitte öffnen Sie Probleme und ziehen Sie dort Anfragen.
Eine plattformübergreifende Registerkartenkomponente für React Native. Implementiert mit react-native-pager-view auf Android & iOS und Panresponder in Web, MacOS und Windows.
Um diese Bibliothek zu verwenden, müssen Sie sicherstellen, dass Sie die richtige Version von React Native verwenden. Wenn Sie eine Version von React Native verwenden, die niedriger als 0.63 ist, müssen Sie diese aktualisieren, bevor Sie versuchen, diese Bibliothek zu verwenden.
react-native-tab-view Version | Erforderliche reagierte native Version |
|---|---|
2.xx | < 0.63 |
3.xx | >= 0.63 |
Öffnen Sie ein Terminal in der Projektwurzel und laufen Sie:
yarn add react-native-tab-view Jetzt müssen wir react-native-pager-view installieren, wenn Sie vorhaben, iOS und Android zu unterstützen.
Wenn Sie die Expo verwenden, um sicherzustellen, dass Sie die kompatiblen Versionen der Bibliotheken erhalten, führen Sie aus:
expo install react-native-pager-viewWenn Sie Expo nicht verwenden, führen Sie Folgendes aus:
yarn add react-native-pager-viewWir sind fertig! Jetzt können Sie die App auf Ihrem Gerät/Simulator erstellen und ausführen.
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 } }
/>
) ;
}Probieren Sie dieses Beispiel auf Snack aus
Das Paket exportiert eine TabView -Komponente, mit der Sie die Registerkartenansicht rendern, und eine TabBar -Komponente, die die Standard -Registerkartenleisten -Implementierung darstellt.
TabViewContainerkomponente verantwortlich für die Rendern und Verwaltung von Registerkarten. Folgt standardmäßig Materialdesignstile.
Grundlegende Nutzung sehen so aus:
< TabView
navigationState = { { index , routes } }
onIndexChange = { setIndex }
renderScene = { SceneMap ( {
first : FirstRoute ,
second : SecondRoute ,
} ) }
/> navigationState ( required )Geben Sie für die Registerkartenansicht an. Der Staat sollte die folgenden Eigenschaften enthalten:
index : Eine Zahl, die den Index der aktiven Route im routes -Array darstelltroutes : Ein Array mit einer Liste von Routenobjekten, die zum Rendern der Registerkarten verwendet werdenJedes Routenobjekt sollte die folgenden Eigenschaften enthalten:
key : Ein eindeutiger Schlüssel zur Identifizierung der Route (erforderlich)title : Titel für die Route in der Registerkartenleiste angezeigticon : Symbol für die Route in der Registerkarte Leiste angezeigtaccessibilityLabel : Barrierefreiheit Beschriftung für die Registerkarte SchaltflächetestID : Test -ID für die Registerkarte SchaltflächeBeispiel:
{
index : 1 ,
routes : [
{ key : 'music' , title : 'Music' } ,
{ key : 'albums' , title : 'Albums' } ,
{ key : 'recents' , title : 'Recents' } ,
{ key : 'purchased' , title : 'Purchased' } ,
]
} TabView ist eine kontrollierte Komponente, was bedeutet, dass der index über den onIndexChange -Rückruf aktualisiert werden muss.
onIndexChange ( required )Rückruf, der auf der Registerkarte Änderung aufgerufen wird, empfängt den Index der neuen Registerkarte als Argument. Der Navigationsstatus muss aktualisiert werden, wenn er aufgerufen wird. Andernfalls wird die Änderung fallen.
renderScene ( required )Rückruf, der ein React -Element zurückgibt, um sie als Seite für die Registerkarte zu rendern. Empfängt ein Objekt, das die Route als Argument enthält:
const renderScene = ( { route , jumpTo } ) => {
switch ( route . key ) {
case 'music' :
return < MusicRoute jumpTo = { jumpTo } /> ;
case 'albums' :
return < AlbumsRoute jumpTo = { jumpTo } /> ;
}
} ; Sie müssen sicherstellen, dass Ihre individuellen Routen ein shouldComponentUpdate um die Leistung zu verbessern. Um die Angabe der Komponenten zu erleichtern, können Sie den SceneMap -Helfer verwenden.
SceneMap nimmt ein Objekt mit der Zuordnung der route.key ein. Key, um Komponenten zu reagieren, und gibt eine Funktion zurück, die mit renderScene Prop verwendet werden soll.
import { SceneMap } from 'react-native-tab-view' ;
...
const renderScene = SceneMap ( {
music : MusicRoute ,
albums : AlbumsRoute ,
} ) ; Das Angeben der Komponenten auf diese Weise ist einfacher und kümmert sich um die Implementierung einer shouldComponentUpdate -Methode.
Jede Szene erhält die folgenden Requisiten:
route : Die aktuelle Route, die von der Komponente gerendert wirdjumpTo : Methode, um auf andere Registerkarten zu springen, nimmt eine route.key Sie als Argumentposition : Animierter Knoten, der die aktuelle Position darstellt Die jumpTo -Methode kann verwendet werden, um programmgesteuert zu anderen Registerkarten zu navigieren:
this . props . jumpTo ( 'albums' ) ; Alle mit SceneMap erzeugten Szenen werden mit React.PureComponent optimiert und werden nicht erneut rendern, wenn sich die Requisiten oder Zustände des Elternteils ändern. Wenn Sie mehr Kontrolle über das Update Ihrer Szenen benötigen (z. B. ein Wiederauflösen des navigationState auslösen, verwenden Sie renderScene direkt anstatt SceneMap zu verwenden.
WICHTIG: Übergeben Sie keine Inline -Funktionen an SceneMap , zum Beispiel nicht Folgendes:
SceneMap ( {
first : ( ) => < FirstRoute foo = { this . props . foo } /> ,
second : SecondRoute ,
} ) ;Definieren Sie Ihre Komponenten immer an anderer Stelle in der oberen Ebene der Datei. Wenn Sie Inline-Funktionen übergeben, werden die Komponenten jeden Rendern neu erstellt, wodurch die gesamte Route dazu führt, dass sie jede Änderung entmontieren und neu renovieren. Es ist sehr schlecht für die Leistung und wird auch dazu führen, dass der lokale Staat verloren geht.
Wenn Sie zusätzliche Requisiten übergeben müssen, verwenden Sie eine benutzerdefinierte renderScene -Funktion:
const renderScene = ( { route } ) => {
switch ( route . key ) {
case 'first' :
return < FirstRoute foo = { this . props . foo } /> ;
case 'second' :
return < SecondRoute /> ;
default :
return null ;
}
} ; renderTabBarRückruf, der ein benutzerdefiniertes React -Element zurückgibt, das als Registerkartenleiste verwendet werden soll:
import { TabBar } from 'react-native-tab-view' ;
...
< TabView
renderTabBar = { props => < TabBar { ... props } /> }
. . .
/ >Wenn dies nicht angegeben ist, wird die Standard -Registerkartenleiste gerendert. Sie übergeben diese Requisiten, um die Standard -Registerkartenleiste anzupassen, Ihre eigene Registerkartenleiste anzugeben, oder deaktivieren Sie die Registerkartenleiste vollständig.
< TabView
renderTabBar = { ( ) => null }
. . .
/ > tabBarPosition Position der Registerkartenleiste in der Registerkartenansicht. Mögliche Werte sind 'top' und 'bottom' . Standardeinstellungen zu 'top' .
lazyFunktion, die ein Objekt mit der aktuellen Route nimmt und einen Booleschen zurückgibt, um anzuzeigen, ob die Szenen träge rendern.
Standardmäßig werden alle Szenen gerendert, um ein reibungsloseres Swipe -Erlebnis zu bieten. Vielleicht möchten Sie das Rendern unkonzentrierter Szenen verschieben, bis der Benutzer sie sieht. Um das faule Rendering für eine bestimmte Szene zu ermöglichen, kehren true von getLazy für diese route zurück:
< TabView
lazy = { ( { route } ) => route . name === 'Albums' }
. . .
/ > Wenn Sie das faule Rendering für einen Bildschirm ermöglichen, dauert es normalerweise einige Zeit, bis es in den Fokus gerendert wird. Sie können den renderLazyPlaceholder -Request verwenden, um anzupassen, was der Benutzer in dieser kurzen Zeit sieht.
Sie können auch einen Booleschen übergeben, um alle Szenen faul zu ermöglichen:
< TabView
lazy
/> lazyPreloadDistance Wenn lazy aktiviert ist, können Sie angeben, wie viele benachbarte Routen mit dieser Requisite vorgeladen werden sollten. Dieser Wert stand auf 0 was bedeutet, dass faule Seiten geladen werden, wenn sie in das Ansichtsfenster kommen.
renderLazyPlaceholder Rückruf, der ein benutzerdefiniertes React -Element zurückgibt, um Routen zu rendern, die noch nicht gerendert wurden. Empfängt ein Objekt, das die Route als Argument enthält. Die lazy Stütze muss auch aktiviert werden.
Diese Ansicht wird normalerweise nur für einen Bruchteil der Sekunde angezeigt. Halten Sie es leicht.
Standardmäßig macht dies null .
keyboardDismissModeZeichenfolge, die angibt, ob die Tastatur als Antwort auf eine Drag -Geste abgewiesen wird. Mögliche Werte sind:
'auto' (Standard): Die Tastatur wird abgewiesen, wenn sich der Index ändert.'on-drag' : Die Tastatur wird abgewiesen, wenn ein Widerstand beginnt.'none' : Ziehen entlassen die Tastatur nicht. swipeEnabled Booleschen Angaben, um Swipe -Gesten zu aktivieren. Swipe -Gesten sind standardmäßig aktiviert. Durch das Durchgeben von false deaktiviert Swipe Gesten, aber der Benutzer kann die Registerkarten durch Drücken der Registerkartenleiste immer noch wechseln.
animationEnabledErmöglicht die Animation beim Ändern der Registerkarte. Standardmäßig ist es wahr.
onSwipeStartRückruf, der aufgerufen wird, wenn die Swipe -Geste beginnt, dh der Benutzer berührt den Bildschirm und bewegt ihn.
onSwipeEndRückruf, der aufgerufen wird, wenn die Swipe -Geste endet, dh der Benutzer hebt den Finger vom Bildschirm nach der Swipe -Geste.
initialLayoutObjekt, das die anfängliche Höhe und Breite der Bildschirme enthält. Durch das Bestehen wird die anfängliche Rendering -Leistung verbessern. Für die meisten Apps ist dies ein guter Standard:
< TabView
initialLayout = { { width : Dimensions . get ( 'window' ) . width } }
. . .
/ > sceneContainerStyleStil für die Ansicht, die jeden Bildschirm einwickelt. Sie können dies übergeben, um einige Standardstile wie Überlaufausschnitte zu überschreiben:
pagerStyleStil für die Pager -Ansicht, um alle Szenen zu wickeln.
styleStil für den Registerkarte anzeigen Container.
TabBar Registerkartenleiste mit Materialdesign. Um die Registerkartenleiste anzupassen, müssten Sie die renderTabBar -Requisite von TabView verwenden, um die TabBar zu rendern und zusätzliche Requisiten zu übergeben.
Um beispielsweise die Anzeigefarbe und die Registerkartenbalken -Hintergrundfarbe anzupassen, können Sie indicatorStyle und style -Requisiten an die TabBar weitergeben:
const renderTabBar = props => (
< TabBar
{ ... props }
indicatorStyle = { { backgroundColor : 'white' } }
style = { { backgroundColor : 'pink' } }
/>
) ;
//...
return (
< TabView
renderTabBar = { renderTabBar }
. . .
/ >
);getLabelText Funktion, die ein Objekt mit der aktuellen Route übernimmt und den Beschriftungstext für die Registerkarte zurückgibt. Verwendet standardmäßig route.title .
< TabBar
getLabelText = { ( { route } ) => route . title }
. . .
/ > getAccessible Funktion, die ein Objekt mit der aktuellen Route nimmt und einen Booleschen zurückgibt, um anzugeben, ob eine Registerkarte als accessible markiert werden soll. Standardmäßig true .
getAccessibilityLabel Funktion, die ein Objekt mit der aktuellen Route übernimmt und eine Barrierefreiheitsbezeichnung für die Registerkartenschaltfläche zurückgibt. Verwendet standardmäßig route.accessibilityLabel , wenn angegeben, andernfalls verwendet der Routentitel.
< TabBar
getAccessibilityLabel = { ( { route } ) => route . accessibilityLabel }
. . .
/ > getTestID Funktion, die ein Objekt mit der aktuellen Route übernimmt und eine Test -ID für die Registerkartenschaltfläche zurückgibt, um diese Registerkarte in den Tests zu finden. Verwendet standardmäßig route.testID .
< TabBar
getTestID = { ( { route } ) => route . testID }
. . .
/ > renderIconFunktion, die ein Objekt mit dem aktuellen Weg, dem fokussierten Status und der Farbe nimmt und ein benutzerdefiniertes React -Element zurückgibt, das als Symbol verwendet werden soll.
< TabBar
renderIcon = { ( { route , focused , color } ) => (
< Icon
name = { focused ? 'albums' : 'albums-outlined' }
color = { color }
/>
) }
. . .
/ > renderLabelFunktion, die ein Objekt mit dem aktuellen Weg, dem fokussierten Status und der Farbe nimmt und ein benutzerdefiniertes React -Element zurückgibt, das als Etikett verwendet werden soll.
< TabBar
renderLabel = { ( { route , focused , color } ) => (
< Text style = { { color , margin : 8 } } >
{ route . title }
</ Text >
) }
. . .
/ > renderTabBarItem Funktion, die ein TabBarItemProps -Objekt übernimmt und ein benutzerdefiniertes React -Element zurückgibt, das als Registerkartenschaltfläche verwendet wird.
renderIndicatorFunktion, die ein Objekt mit der aktuellen Route nimmt und ein benutzerdefiniertes React -Element zurückgibt, das als Registerkartenanzeige verwendet werden soll.
renderBadgeFunktion, die ein Objekt mit der aktuellen Route nimmt und ein benutzerdefiniertes React -Element zurückgibt, das als Abzeichen verwendet werden soll.
onTabPressFunktion zum Ausführen auf der Registerkarte Drücken. Es empfängt die Szene für die gedrückte Registerkarte, nützlich für Dinge wie Scrollen nach oben.
Standardmäßig schaltet die Registerkarte auch die Registerkarte. Um dieses Verhalten zu verhindern, können Sie preventDefault aufrufen:
< TabBar
onTabPress = { ( { route , preventDefault } ) => {
if ( route . key === 'home' ) {
preventDefault ( ) ;
// Do something else
}
} }
. . .
/ > onTabLongPressFunktion zum Ausführen auf der Registerkarte Long Drücken Sie für Dinge wie das Anzeigen eines Menüs mit weiteren Optionen
activeColorBenutzerdefinierte Farbe für Symbol und Beschriftung in der aktiven Registerkarte.
inactiveColorBenutzerdefinierte Farbe für Symbol und Beschriftung auf der Registerkarte "Inaktive".
pressColorFarbe für materielle Ripple (nur Android> = 5,0).
pressOpacityDeckkraft für gedrückte Registerkarte (nur iOS und Android <5.0).
scrollEnabledBoolescher Anmelde, ob die Registerkartenleiste scrollbar werden soll.
Wenn Sie scrollEnabled auf true festgelegt sind, sollten Sie auch eine width in tabStyle angeben, um das anfängliche Render zu verbessern.
bouncesBoolean gibt an, ob die Registerkartenleiste beim Scrollen abprallt.
tabStyleStil für die individuellen Registerkartenelemente in der Registerkartenleiste.
Standardmäßig nehmen alle Registerkartenelemente die gleiche vorbereitete Breite auf, basierend auf der Breite des Containers. Wenn Sie möchten, dass sie ihre ursprüngliche Breite einnehmen, können Sie width: 'auto' in tabStyle .
indicatorStyleStil für den aktiven Indikator angewendet.
indicatorContainerStyleStil für die Containeransicht für den Indikator.
labelStyleStil für das Registerkarte Element -Etikett.
contentContainerStyleStil für den inneren Behälter für Registerkarten angewendet werden.
styleStil für den Registerkartenbehälter angewendet.
gapDefinieren Sie einen Abstand zwischen den Registerkarten.
testIDTest -ID für die Tabbar. Kann zum Scrollen der Tab -Balken in Tests verwendet werden
Wenn Sie die Registerkartenansicht in das Navigationssystem der React Navigation integrieren möchten, möchten Sie z. B. mithilfe navigation.navigate zu einer Registerkarte navigieren.
Beachten Sie, dass mit der React Navigation 4 -Integration aufgrund der Einschränkungen bei der React -Navigation einige Funktionen nicht verfügbar sind. Zum Beispiel ist es möglich, die gerenderten Registerkarten dynamisch zu ändern.
Die renderScene -Funktion wird jedes Mal aufgerufen, wenn sich der Index ändert. Wenn Ihre renderScene Funktion teuer ist, ist es eine gute Idee, jede Route in eine separate Komponente zu verschieben, wenn sie nicht vom Index abhängen, und die Verwendung shouldComponentUpdate oder React.memo in Ihren Routenkomponenten, um unnötige Neuanschläge zu verhindern.
Zum Beispiel statt:
const renderScene = ( { route } ) => {
switch ( route . key ) {
case 'home' :
return (
< View style = { styles . page } >
< Avatar />
< NewsFeed />
</ View >
) ;
default :
return null ;
}
} ;Folgendes machen:
const renderScene = ( { route } ) => {
switch ( route . key ) {
case 'home' :
return < HomeComponent /> ;
default :
return null ;
}
} ; Wobei <HomeComponent /> ein PureComponent ist, wenn Sie Klassenkomponenten verwenden:
export default class HomeComponent extends React . PureComponent {
render ( ) {
return (
< View style = { styles . page } >
< Avatar />
< NewsFeed />
</ View >
) ;
}
} Oder, in React.memo eingewickelt, wenn Sie Funktionskomponenten verwenden:
function HomeComponent ( ) {
return (
< View style = { styles . page } >
< Avatar />
< NewsFeed />
</ View >
) ;
}
export default React . memo ( HomeComponent ) ;Wir müssen die Breite des Behälters messen und daher warten, bevor wir einige Elemente auf dem Bildschirm rendern. Wenn Sie die anfängliche Breite im Voraus kennen, können Sie sie weitergeben und wir müssen nicht darauf warten, sie zu messen. Meistens ist es nur die Fensterbreite.
Übergeben Sie beispielsweise das folgende initialLayout an TabView :
const initialLayout = {
height : 0 ,
width : Dimensions . get ( 'window' ) . width ,
} ;Die Registerkartenansicht reagiert weiterhin auf Änderungen in der Dimension und passt entsprechend an, um Dinge wie die Orientierungsänderung aufzunehmen.
Wenn Sie eine große Anzahl von Routen, insbesondere Bildern, haben, kann die Animation viel verlangsamen. Sie können stattdessen eine begrenzte Anzahl von Routen wiederholen.
Führen Sie beispielsweise Folgendes aus, um nur 2 Routen auf jeder Seite zu rendern:
const renderScene = ( { route } ) => {
if ( Math . abs ( index - routes . indexOf ( route ) ) > 2 ) {
return < View /> ;
}
return < MySceneComponent route = { route } /> ;
} ; Wenn Sie die TabView in einem vertikalen ScrollView nisten, deaktivieren Sie die Optimierungen in den FlatList -Komponenten, die in der TabView gerendert wurden. Vermeiden Sie es also, wenn möglich zu tun.
lazy und renderLazyPlaceholder -Hälter -Requisiten, um Routen nach Bedarf zu rendern Die lazy Option ist standardmäßig deaktiviert, um ein reibungsloseres Registerkarte zu bieten. Das Aktivieren von lazy kann die anfängliche Lastleistung verbessern, indem sie nur dann Routen rendern, wenn sie in Sicht kommen. Weitere Informationen finden Sie in der Referenzreferenz.
Während der Entwicklung können Sie die Beispiel -App ausführen, um Ihre Änderungen zu testen.
Stellen Sie sicher, dass Ihr Code TypeScript und Eslint übergibt. Führen Sie Folgendes aus, um zu überprüfen:
yarn typescript
yarn lintFühren Sie Folgendes aus, um Formatierungsfehler zu beheben:
yarn lint -- --fixDenken Sie daran, wenn möglich Tests für Ihre Änderung hinzuzufügen.