このレポはhttps://github.com/react-navigation/react-navigation/tree/main/packages/react-native-tab-viewに移動しました。問題を開いて、そこにリクエストをプルしてください。
Reactネイティブのクロスプラットフォームタブビューコンポーネント。 Android&iOSでreact-native-pager-viewを使用して実装し、Web、MacOS、およびWindowsでPanesponderを使用して実装しました。
このライブラリを使用するには、Reactネイティブの正しいバージョンを使用していることを確認する必要があります。 0.63未満のReactネイティブのバージョンを使用している場合、このライブラリを使用しようとする前に、それをアップグレードする必要があります。
react-native-tab-viewバージョン | 必要なReact Nativeバージョン |
|---|---|
2.xx | < 0.63 |
3.xx | >= 0.63 |
プロジェクトルートで端末を開き、実行します。
yarn add react-native-tab-view iOSとAndroidをサポートする予定がある場合はreact-native-pager-viewをインストールする必要があります。
博覧会を使用している場合は、ライブラリの互換性のあるバージョンを取得するようにしてください。
expo install react-native-pager-view博覧会を使用していない場合は、以下を実行してください。
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コンポーネントをエクスポートします。Tabviewコンポーネントは、タブビューをレンダリングするために使用するコンポーネントと、デフォルトのタブバーの実装であるTabBarコンポーネントをエクスポートします。
TabViewタブのレンダリングと管理を担当するコンテナコンポーネント。デフォルトでは、マテリアルデザインスタイルに従います。
基本的な使用法は次のようになります:
< TabView
navigationState = { { index , routes } }
onIndexChange = { setIndex }
renderScene = { SceneMap ( {
first : FirstRoute ,
second : SecondRoute ,
} ) }
/> navigationState ( required )タブビューの状態。州には、次のプロパティを含める必要があります。
index : routesアレイのアクティブルートのインデックスを表す数字routes :タブのレンダリングに使用されるルートオブジェクトのリストを含む配列各ルートオブジェクトには、次のプロパティが含まれている必要があります。
key :ルートを識別するユニークなキー(必須)title :タブバーに表示するルートのタイトルicon :タブバーに表示するルートのアイコンaccessibilityLabel :[タブ]ボタンのアクセシビリティラベルtestID :タブボタンのテストID例:
{
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 )[React要素を返すコールバック]タブのページとしてレンダリングします。引数としてルートを含むオブジェクトを受信します。
const renderScene = ( { route , jumpTo } ) => {
switch ( route . key ) {
case 'music' :
return < MusicRoute jumpTo = { jumpTo } /> ;
case 'albums' :
return < AlbumsRoute jumpTo = { jumpTo } /> ;
}
} ;パフォーマンスを改善するために、個々のルートがshouldComponentUpdateを実装することを確認する必要があります。コンポーネントを簡単に指定できるようにするには、 SceneMapヘルパーを使用できます。
SceneMap 、 route.keyのマッピングを備えたオブジェクトを使用して、コンポーネントを反応させ、 renderScene propで使用する関数を返します。
import { SceneMap } from 'react-native-tab-view' ;
...
const renderScene = SceneMap ( {
music : MusicRoute ,
albums : AlbumsRoute ,
} ) ;この方法でコンポーネントを指定する方が簡単で、 shouldComponentUpdateメソッドの実装に対応します。
各シーンは次の小道具を受け取ります。
route :コンポーネントによってレンダリングされた現在のルートjumpTo :他のタブにジャンプする方法は、それが引数であるのでroute.keyを取ります。position :現在の位置を表すアニメーションノードjumpToメソッドを使用して、プログラムで他のタブに移動できます。
this . props . jumpTo ( 'albums' ) ; SceneMapでレンダリングされたすべてのシーンは、 React.PureComponentを使用して最適化され、親の小道具や状態が変更されたときに再レンダリングしないでください。シーンがどのように更新されるか(たとえば、 navigationStateが変更されなかった場合でも再レンダーをトリガーする)をさらに制御する必要がある場合は、 SceneMapを使用する代わりにrenderScene直接使用します。
重要:たとえば、インライン関数を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タブビューのタブバーの位置。考えられる値は'top'と'bottom'です。デフォルトは'top'になります。
lazy現在のルートでオブジェクトを取得し、ブール値を返して、シーンをゆっくりとレンダリングするかどうかを示す関数。
デフォルトでは、すべてのシーンがスムーズなスワイプエクスペリエンスを提供するようにレンダリングされます。ただし、ユーザーが表示されるまで、焦点を絞られていないシーンのレンダリングを延期したい場合があります。特定のシーンの怠zyなレンダリングを有効にするには、そのrouteのgetLazyからtrueを返します。
< TabView
lazy = { ( { route } ) => route . name === 'Albums' }
. . .
/ >画面の怠zyなレンダリングを有効にすると、通常、焦点が合ったときにレンダリングに時間がかかります。 renderLazyPlaceholder Propを使用して、この短期間にユーザーが見たものをカスタマイズできます。
また、すべてのシーンで怠zyを有効にするためにブール値を渡すこともできます。
< TabView
lazy
/> lazyPreloadDistance lazyが有効になっている場合、この小道具を使用してプリロードする隣接ルートの数を指定できます。この値はデフォルトです0つまり、怠zyなページがビューポートに入るとロードされることを意味します。
renderLazyPlaceholderまだレンダリングされていないルートのレンダリングにカスタムReact要素を返すコールバック。引数としてルートを含むオブジェクトを受信します。 lazy小道具も有効にする必要があります。
このビューは通常、一瞬だけ表示されます。軽量に保ちます。
デフォルトでは、これはnullをレンダリングします。
keyboardDismissModeドラッグジェスチャーに応じてキーボードが却下されるかどうかを示す文字列。考えられる値は次のとおりです。
'auto' (デフォルト):インデックスが変更されると、キーボードが却下されます。'on-drag' :ドラッグが始まるとキーボードが却下されます。'none' :ドラッグはキーボードを却下しません。 swipeEnabledスワイプジェスチャーを有効にするかどうかを示すブール。スワイプジェスチャーはデフォルトで有効になります。 falseを渡すとスワイプジェスチャーが無効になりますが、ユーザーはタブバーを押すことでタブを切り替えることができます。
animationEnabledタブを変更するときにアニメーションを有効にします。デフォルトではそれは本当です。
onSwipeStartスワイプジェスチャーが起動したときに呼び出されるコールバック、つまりユーザーが画面に触れて移動します。
onSwipeEndスワイプジェスチャーが終了したときに呼び出されるコールバック、つまり、スワイプジェスチャーの後にユーザーが画面から指を上げます。
initialLayout画面の初期高さと幅を含むオブジェクト。これに合格すると、最初のレンダリングパフォーマンスが向上します。ほとんどのアプリの場合、これは良いデフォルトです。
< TabView
initialLayout = { { width : Dimensions . get ( 'window' ) . width } }
. . .
/ > sceneContainerStyle各画面をラッピングするビューに適用するスタイル。これを渡して、オーバーフロークリッピングなどのデフォルトスタイルをオーバーライドできます。
pagerStyleすべてのシーンをラッピングするポケットベルビューに適用するスタイル。
styleタブビューコンテナに適用するスタイル。
TabBarマテリアルデザインをテーマにしたタブバー。 Tab Barをカスタマイズするには、 TabViewのrenderTabBar Propを使用して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現在のルートでオブジェクトを取得し、[タブ]ボタンのテストIDを返して、このタブボタンをテストに配置します。デフォルトで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現在のルートでオブジェクトを取得し、タブインジケータとして使用するカスタムReact要素を返す関数。
renderBadge現在のルートでオブジェクトを取得し、バッジとして使用するカスタムReact要素を返す関数。
onTabPressタブプレスで実行する機能。プレスされたタブのシーンを受け取ります。これは、スクロールなどに役立ちます。
デフォルトでは、タブプレスもタブを切り替えます。この動作を防ぐために、 preventDefaultを呼び出すことができます。
< TabBar
onTabPress = { ( { route , preventDefault } ) => {
if ( route . key === 'home' ) {
preventDefault ( ) ;
// Do something else
}
} }
. . .
/ > onTabLongPressタブロングプレスで実行する機能、より多くのオプションを備えたメニューを表示するようなものに使用します
activeColorアクティブタブのアイコンとラベルのカスタムカラー。
inactiveColor非アクティブタブのアイコンとラベルのカスタムカラー。
pressColorマテリアルリップルの色(Android> = 5.0のみ)。
pressOpacity押されたタブの不透明度(iOSおよびAndroid <5.0のみ)。
scrollEnabledタブバーをスクロール可能にするかどうかを示すブール。
scrollEnabled trueに設定した場合は、 tabStyleのwidthを指定して、初期レンダリングを改善する必要があります。
bouncesスクロール時にタブバーが跳ね返るかどうかを示すブール。
tabStyleタブバーの個々のタブアイテムに適用するスタイル。
デフォルトでは、すべてのタブ項目は、コンテナの幅に基づいて同じ事前計算された幅を取り上げます。元の幅を取得したい場合は、 tabStyleでwidth: 'auto'を指定できます。
indicatorStyleアクティブなインジケーターに適用するスタイル。
indicatorContainerStyleインジケーターのコンテナビューに適用するスタイル。
labelStyleタブアイテムラベルに適用するスタイル。
contentContainerStyleタブの内側のコンテナに適用するスタイル。
styleタブバーコンテナに適用するスタイル。
gapタブ間の間隔を定義します。
testIDTabbarのテストID。テストでタブバーをスクロールするために使用できます
Tab ViewをReact Navigationのナビゲーションシステムと統合する場合は、 navigation.navigateなどを使用してタブに移動できるようにすることができます。次の公式統合を使用できます。
React Navigationの制限があるため、React Navigation 4統合では機能が利用できないことに注意してください。たとえば、レンダリングされたタブを動的に変更することができます。
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を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 } /> ;
} ;垂直ScrollView内のTabViewをネストすると、 TabView内でレンダリングされたFlatListコンポーネントの最適化が無効になります。可能であればそれを避けてください。
lazyとrenderLazyPlaceholder小道具を使用してくださいlazyオプションは、デフォルトではよりスムーズなタブスイッチングエクスペリエンスを提供するために無効になっていますが、それを有効にして、より良い怠zyなロードエクスペリエンスのためにプレースホルダーコンポーネントを提供できます。 lazyを有効にすると、ルートが表示されたときにのみレンダリングすることにより、初期負荷のパフォーマンスを向上させることができます。詳細については、プロップリファレンスを参照してください。
開発中に、サンプルアプリを実行して変更をテストできます。
コードがタイプスクリプトとeslintに合格していることを確認してください。確認するには、次のことを実行してください。
yarn typescript
yarn lintフォーマットエラーを修正するには、以下を実行します。
yarn lint -- --fix可能であれば、変更のテストを追加することを忘れないでください。