Repo telah dipindahkan ke https://github.com/react-navigation/react-navigation/tree/main/packages/react-native-tab-view. Harap buka masalah dan tarik permintaan di sana.
Komponen tampilan tab lintas platform untuk React Native. Diimplementasikan menggunakan react-native-pager-view di Android & iOS, dan PanResponder di web, macOS, dan Windows.
Untuk menggunakan perpustakaan ini, Anda perlu memastikan Anda menggunakan versi React Native yang benar. Jika Anda menggunakan versi Native React yang lebih rendah dari 0.63 Anda perlu memutakhirkannya sebelum mencoba menggunakan perpustakaan ini.
Versi react-native-tab-view | Diperlukan Versi Native React |
|---|---|
2.xx | < 0.63 |
3.xx | >= 0.63 |
Buka terminal di root proyek dan jalankan:
yarn add react-native-tab-view Sekarang kita perlu menginstal react-native-pager-view jika Anda berencana untuk mendukung iOS dan Android.
Jika Anda menggunakan Expo, untuk memastikan bahwa Anda mendapatkan versi perpustakaan yang kompatibel, jalankan:
expo install react-native-pager-viewJika Anda tidak menggunakan Expo, jalankan yang berikut:
yarn add react-native-pager-viewKami selesai! Sekarang Anda dapat membangun dan menjalankan aplikasi di perangkat/simulator Anda.
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 } }
/>
) ;
}Coba contoh ini saat camilan
Paket mengekspor komponen TabView yang merupakan yang Anda gunakan untuk membuat tampilan tab, dan komponen TabBar yang merupakan implementasi bilah tab default.
TabViewKomponen kontainer yang bertanggung jawab untuk rendering dan mengelola tab. Mengikuti gaya desain material secara default.
Penggunaan dasar terlihat seperti ini:
< TabView
navigationState = { { index , routes } }
onIndexChange = { setIndex }
renderScene = { SceneMap ( {
first : FirstRoute ,
second : SecondRoute ,
} ) }
/> navigationState ( required )Menyatakan untuk tampilan tab. Negara harus berisi sifat -sifat berikut:
index : Angka yang mewakili indeks rute aktif di array routesroutes : Array yang berisi daftar objek rute yang digunakan untuk membuat tabSetiap objek rute harus berisi sifat -sifat berikut:
key : Kunci unik untuk mengidentifikasi rute (diperlukan)title : Judul untuk rute yang akan ditampilkan di Tab Baricon : Ikon untuk rute yang akan ditampilkan di bilah tabaccessibilityLabel : Label aksesibilitas untuk tombol tabtestID : ID uji untuk tombol tabContoh:
{
index : 1 ,
routes : [
{ key : 'music' , title : 'Music' } ,
{ key : 'albums' , title : 'Albums' } ,
{ key : 'recents' , title : 'Recents' } ,
{ key : 'purchased' , title : 'Purchased' } ,
]
} TabView adalah komponen yang dikendalikan, yang berarti index perlu diperbarui melalui panggilan balik onIndexChange .
onIndexChange ( required )Callback yang dipanggil pada perubahan tab, menerima indeks tab baru sebagai argumen. Negara navigasi perlu diperbarui ketika dipanggil, jika tidak perubahannya dijatuhkan.
renderScene ( required )Callback yang mengembalikan elemen bereaksi untuk merender sebagai halaman untuk tab. Menerima objek yang berisi rute sebagai argumen:
const renderScene = ( { route , jumpTo } ) => {
switch ( route . key ) {
case 'music' :
return < MusicRoute jumpTo = { jumpTo } /> ;
case 'albums' :
return < AlbumsRoute jumpTo = { jumpTo } /> ;
}
} ; Anda perlu memastikan bahwa rute pribadi Anda menerapkan A shouldComponentUpdate untuk meningkatkan kinerja. Untuk membuatnya lebih mudah untuk menentukan komponen, Anda dapat menggunakan helper SceneMap .
SceneMap mengambil objek dengan pemetaan route.key untuk bereaksi komponen dan mengembalikan fungsi untuk digunakan dengan renderScene prop.
import { SceneMap } from 'react-native-tab-view' ;
...
const renderScene = SceneMap ( {
music : MusicRoute ,
albums : AlbumsRoute ,
} ) ; Menentukan komponen dengan cara ini lebih mudah dan menangani menerapkan metode shouldComponentUpdate .
Setiap adegan menerima alat peraga berikut:
route : Rute saat ini yang diberikan oleh komponenjumpTo : Metode untuk melompat ke tab lain, mengambil route.key karena argumennyaposition : Node animasi yang mewakili posisi saat ini Metode jumpTo dapat digunakan untuk menavigasi ke tab lain secara terprogram:
this . props . jumpTo ( 'albums' ) ; Semua adegan yang diberikan dengan SceneMap dioptimalkan menggunakan React.PureComponent dan jangan render ulang ketika props atau status orang tua berubah. Jika Anda membutuhkan lebih banyak kontrol atas bagaimana pembaruan adegan Anda (misalnya - memicu render ulang bahkan jika navigationState tidak berubah), gunakan renderScene secara langsung alih -alih menggunakan SceneMap .
PENTING: Jangan lulus fungsi inline ke SceneMap , misalnya, jangan lakukan hal berikut:
SceneMap ( {
first : ( ) => < FirstRoute foo = { this . props . foo } /> ,
second : SecondRoute ,
} ) ;Selalu tentukan komponen Anda di tempat lain di tingkat atas file. Jika Anda lulus fungsi inline, itu akan menciptakan kembali komponen setiap render, yang akan menyebabkan seluruh rute untuk tidak menghitung dan mengulangi setiap perubahan. Sangat buruk untuk kinerja dan juga akan menyebabkan negara bagian mana pun hilang.
Jika Anda perlu melewati alat peraga tambahan, gunakan fungsi renderScene khusus:
const renderScene = ( { route } ) => {
switch ( route . key ) {
case 'first' :
return < FirstRoute foo = { this . props . foo } /> ;
case 'second' :
return < SecondRoute /> ;
default :
return null ;
}
} ; renderTabBarCallback yang mengembalikan elemen reaksi khusus untuk digunakan sebagai bilah tab:
import { TabBar } from 'react-native-tab-view' ;
...
< TabView
renderTabBar = { props => < TabBar { ... props } /> }
. . .
/ >Jika ini tidak ditentukan, bilah tab default diberikan. Anda melewati alat peraga ini untuk menyesuaikan bilah tab default, menyediakan bilah tab Anda sendiri, atau menonaktifkan bilah tab sepenuhnya.
< TabView
renderTabBar = { ( ) => null }
. . .
/ > tabBarPosition Posisi bilah tab di tampilan tab. Nilai yang mungkin adalah 'top' dan 'bottom' . Default ke 'top' .
lazyFungsi yang mengambil objek dengan rute saat ini dan mengembalikan boolean untuk menunjukkan apakah akan malas membuat adegan.
Secara default semua adegan diberikan untuk memberikan pengalaman gesek yang lebih halus. Tetapi Anda mungkin ingin menunda render adegan yang tidak fokus sampai pengguna melihatnya. Untuk mengaktifkan rendering malas untuk adegan tertentu, kembali true dari getLazy untuk route itu:
< TabView
lazy = { ( { route } ) => route . name === 'Albums' }
. . .
/ > Saat Anda mengaktifkan rendering malas untuk layar, biasanya akan membutuhkan waktu untuk membuat ketika menjadi fokus. Anda dapat menggunakan prop renderLazyPlaceholder untuk menyesuaikan apa yang dilihat pengguna selama periode singkat ini.
Anda juga dapat melewati boolean untuk memungkinkan malas untuk semua adegan:
< TabView
lazy
/> lazyPreloadDistance Saat lazy diaktifkan, Anda dapat menentukan berapa banyak rute yang berdekatan yang harus dimuat dengan prop ini. Nilai ini default ke 0 yang berarti halaman malas dimuat saat masuk ke viewport.
renderLazyPlaceholder Callback yang mengembalikan elemen React khusus ke render untuk rute yang belum diterjemahkan. Menerima objek yang berisi rute sebagai argumen. Prop lazy juga perlu diaktifkan.
Tampilan ini biasanya hanya ditampilkan selama sepersekian detik. Tetap ringan.
Secara default, ini membuat null .
keyboardDismissModeString menunjukkan apakah keyboard diberhentikan sebagai tanggapan terhadap gerakan seret. Nilai yang mungkin adalah:
'auto' (default): Keyboard diberhentikan ketika indeks berubah.'on-drag' : Keyboard diberhentikan ketika hambatan dimulai.'none' : Drags jangan abaikan keyboard. swipeEnabled Boolean menunjukkan apakah akan mengaktifkan gerakan gesek. Gerakan gesek diaktifkan secara default. Melewati false akan menonaktifkan gerakan gesek, tetapi pengguna masih dapat mengganti tab dengan menekan bilah tab.
animationEnabledMengaktifkan animasi saat mengubah tab. Secara default itu benar.
onSwipeStartCallback yang dipanggil saat gerakan gesek dimulai, yaitu pengguna menyentuh layar dan memindahkannya.
onSwipeEndCallback yang disebut saat gerakan gesek berakhir, yaitu pengguna mengangkat jari mereka dari layar setelah gerakan gesek.
initialLayoutObjek yang berisi tinggi dan lebar awal layar. Melewati ini akan meningkatkan kinerja rendering awal. Untuk sebagian besar aplikasi, ini adalah default yang bagus:
< TabView
initialLayout = { { width : Dimensions . get ( 'window' ) . width } }
. . .
/ > sceneContainerStyleGaya untuk diterapkan pada tampilan yang membungkus setiap layar. Anda dapat melewati ini untuk mengganti beberapa gaya default seperti kliping overflow:
pagerStyleGaya untuk diterapkan pada tampilan pager yang membungkus semua adegan.
styleGaya untuk diterapkan pada wadah tampilan tab.
TabBar Bar Tab Tema Desain Bahan. Untuk menyesuaikan bilah tab, Anda harus menggunakan renderTabBar Prop of TabView untuk membuat TabBar dan melewati alat peraga tambahan.
Misalnya, untuk menyesuaikan warna indikator dan warna latar belakang bilah tab, Anda dapat meneruskan indicatorStyle dan alat peraga style ke TabBar masing -masing:
const renderTabBar = props => (
< TabBar
{ ... props }
indicatorStyle = { { backgroundColor : 'white' } }
style = { { backgroundColor : 'pink' } }
/>
) ;
//...
return (
< TabView
renderTabBar = { renderTabBar }
. . .
/ >
);getLabelText Fungsi yang mengambil objek dengan rute saat ini dan mengembalikan teks label untuk tab. Menggunakan route.title secara default.
< TabBar
getLabelText = { ( { route } ) => route . title }
. . .
/ > getAccessible Fungsi yang mengambil objek dengan rute saat ini dan mengembalikan boolean untuk menunjukkan apakah akan menandai tab sebagai accessible . Default ke true .
getAccessibilityLabel Fungsi yang mengambil objek dengan rute saat ini dan mengembalikan label aksesibilitas untuk tombol tab. Menggunakan route.accessibilityLabel secara default jika ditentukan, jika tidak menggunakan judul rute.
< TabBar
getAccessibilityLabel = { ( { route } ) => route . accessibilityLabel }
. . .
/ > getTestID Fungsi yang mengambil objek dengan rute saat ini dan mengembalikan ID tes untuk tombol tab untuk menemukan tombol tab ini dalam tes. Menggunakan route.testID secara default.
< TabBar
getTestID = { ( { route } ) => route . testID }
. . .
/ > renderIconFungsi yang mengambil objek dengan rute saat ini, status terfokus dan warna dan mengembalikan elemen reaksi khusus untuk digunakan sebagai ikon.
< TabBar
renderIcon = { ( { route , focused , color } ) => (
< Icon
name = { focused ? 'albums' : 'albums-outlined' }
color = { color }
/>
) }
. . .
/ > renderLabelFungsi yang mengambil objek dengan rute saat ini, status terfokus dan warna dan mengembalikan elemen reaksi khusus untuk digunakan sebagai label.
< TabBar
renderLabel = { ( { route , focused , color } ) => (
< Text style = { { color , margin : 8 } } >
{ route . title }
</ Text >
) }
. . .
/ > renderTabBarItem Fungsi yang mengambil objek TabBarItemProps dan mengembalikan elemen React khusus untuk digunakan sebagai tombol tab.
renderIndicatorFungsi yang mengambil objek dengan rute saat ini dan mengembalikan elemen reaksi khusus untuk digunakan sebagai indikator tab.
renderBadgeFungsi yang mengambil objek dengan rute saat ini dan mengembalikan elemen reaksi khusus untuk digunakan sebagai lencana.
onTabPressFungsi untuk dieksekusi pada Tab Press. Ini menerima adegan untuk tab yang ditekan, berguna untuk hal -hal seperti gulir ke atas.
Secara default, Tab Press juga mengganti tab. Untuk mencegah perilaku ini, Anda dapat menghubungi preventDefault :
< TabBar
onTabPress = { ( { route , preventDefault } ) => {
if ( route . key === 'home' ) {
preventDefault ( ) ;
// Do something else
}
} }
. . .
/ > onTabLongPressFungsi untuk dijalankan pada Tab Long Press, gunakan untuk hal -hal seperti menampilkan menu dengan lebih banyak opsi
activeColorWarna khusus untuk ikon dan label di tab Aktif.
inactiveColorWarna khusus untuk ikon dan label di tab yang tidak aktif.
pressColorWarna untuk riak material (Android> = 5.0 saja).
pressOpacityOpacity for Pressed Tab (iOS dan Android <5.0 saja).
scrollEnabledBoolean menunjukkan apakah akan membuat bilah tab dapat digulir.
Jika Anda mengatur scrollEnabled ke true , Anda juga harus menentukan width tabStyle untuk meningkatkan render awal.
bouncesBoolean menunjukkan apakah bar tab memantul saat menggulir.
tabStyleGaya untuk diterapkan pada item tab individual di bilah tab.
Secara default, semua item tab mengambil lebar pra-penghitungan yang sama berdasarkan lebar wadah. Jika Anda ingin mereka mengambil lebar aslinya, Anda dapat menentukan width: 'auto' di tabStyle .
indicatorStyleGaya untuk diterapkan pada indikator aktif.
indicatorContainerStyleGaya untuk diterapkan pada tampilan kontainer untuk indikator.
labelStyleGaya untuk diterapkan pada label item tab.
contentContainerStyleGaya untuk diterapkan pada wadah dalam untuk tab.
styleGaya untuk diterapkan pada wadah Bar Tab.
gapTentukan jarak antar tab.
testIDID Uji untuk Tabbar. Dapat digunakan untuk menggulir bilah tab dalam tes
Jika Anda ingin mengintegrasikan tampilan tab dengan sistem navigasi Navigasi React, misalnya ingin dapat menavigasi ke tab menggunakan navigation.navigate dll, Anda dapat menggunakan integrasi resmi berikut:
Perhatikan bahwa beberapa fungsi tidak tersedia dengan integrasi React Navigation 4 karena keterbatasan navigasi bereaksi. Misalnya, dimungkinkan untuk secara dinamis mengubah tab yang diberikan.
Fungsi renderScene dipanggil setiap kali indeks berubah. Jika fungsi renderScene Anda mahal, itu ide yang baik, pindahkan setiap rute ke komponen terpisah jika tidak bergantung pada indeks, dan gunakan shouldComponentUpdate atau React.memo dalam komponen rute Anda untuk mencegah re-render yang tidak perlu.
Misalnya, alih -alih:
const renderScene = ( { route } ) => {
switch ( route . key ) {
case 'home' :
return (
< View style = { styles . page } >
< Avatar />
< NewsFeed />
</ View >
) ;
default :
return null ;
}
} ;Lakukan hal berikut:
const renderScene = ( { route } ) => {
switch ( route . key ) {
case 'home' :
return < HomeComponent /> ;
default :
return null ;
}
} ; Di mana <HomeComponent /> adalah komponen PureComponent jika Anda menggunakan komponen kelas:
export default class HomeComponent extends React . PureComponent {
render ( ) {
return (
< View style = { styles . page } >
< Avatar />
< NewsFeed />
</ View >
) ;
}
} Atau, dibungkus dengan React.memo jika Anda menggunakan komponen fungsi:
function HomeComponent ( ) {
return (
< View style = { styles . page } >
< Avatar />
< NewsFeed />
</ View >
) ;
}
export default React . memo ( HomeComponent ) ;Kita perlu mengukur lebar wadah dan karenanya perlu menunggu sebelum membuat beberapa elemen di layar. Jika Anda tahu lebar awal di muka, Anda dapat meneruskannya dan kami tidak perlu menunggu untuk mengukurnya. Sebagian besar waktu, itu hanya lebar jendela.
Misalnya, berikan initialLayout berikut ke TabView :
const initialLayout = {
height : 0 ,
width : Dimensions . get ( 'window' ) . width ,
} ;Tampilan tab masih akan bereaksi terhadap perubahan dimensi dan menyesuaikannya untuk mengakomodasi hal -hal seperti perubahan orientasi.
Jika Anda memiliki sejumlah besar rute, terutama gambar, itu dapat banyak memperlambat animasi. Anda malah dapat membuat sejumlah rute terbatas.
Misalnya, lakukan hal berikut untuk membuat hanya 2 rute di setiap sisi:
const renderScene = ( { route } ) => {
if ( Math . abs ( index - routes . indexOf ( route ) ) > 2 ) {
return < View /> ;
}
return < MySceneComponent route = { route } /> ;
} ; Nesting TabView di dalam ScrollView vertikal akan menonaktifkan optimisasi dalam komponen FlatList yang diberikan di dalam TabView . Jadi hindari melakukannya jika memungkinkan.
lazy dan renderLazyPlaceholder untuk membuat rute sesuai kebutuhan Opsi lazy dinonaktifkan secara default untuk memberikan pengalaman switching tab yang lebih halus, tetapi Anda dapat mengaktifkannya dan memberikan komponen placeholder untuk pengalaman pemuatan malas yang lebih baik. Mengaktifkan lazy dapat meningkatkan kinerja beban awal dengan rendering rute hanya ketika mereka terlihat. Rujuk referensi prop untuk detail lebih lanjut.
Saat berkembang, Anda dapat menjalankan aplikasi contoh untuk menguji perubahan Anda.
Pastikan kode Anda melewati naskah dan eslint. Jalankan yang berikut untuk memverifikasi:
yarn typescript
yarn lintUntuk memperbaiki kesalahan pemformatan, jalankan yang berikut:
yarn lint -- --fixIngatlah untuk menambahkan tes untuk perubahan Anda jika memungkinkan.