diff --git a/README.md b/README.md index d194a0e0..63bc9e63 100644 --- a/README.md +++ b/README.md @@ -308,6 +308,10 @@ String indicating whether the keyboard gets dismissed in response to a drag gest Boolean indicating whether to enable swipe gestures. Swipe gestures are enabled by default. Passing `false` will disable swipe gestures, but the user can still switch tabs by pressing the tab bar. +#### `animationEnabled` + +Enables animation when changing tab. By default it's true. + ##### `onSwipeStart` Callback which is called when the swipe gesture starts, i.e. the user touches the screen and moves it. diff --git a/src/PagerViewAdapter.tsx b/src/PagerViewAdapter.tsx index b858cb48..bd27e7b7 100644 --- a/src/PagerViewAdapter.tsx +++ b/src/PagerViewAdapter.tsx @@ -41,6 +41,7 @@ export default function PagerViewAdapter({ onSwipeEnd, children, style, + animationEnabled, ...rest }: Props) { const { index } = navigationState; @@ -58,13 +59,21 @@ export default function PagerViewAdapter({ navigationStateRef.current = navigationState; }); - const jumpTo = React.useCallback((key: string) => { - const index = navigationStateRef.current.routes.findIndex( - (route: { key: string }) => route.key === key - ); - - pagerRef.current?.setPage(index); - }, []); + const jumpTo = React.useCallback( + (key: string) => { + const index = navigationStateRef.current.routes.findIndex( + (route: { key: string }) => route.key === key + ); + + if (animationEnabled) { + pagerRef.current?.setPage(index); + } else { + pagerRef.current?.setPageWithoutAnimation(index); + position.setValue(index); + } + }, + [animationEnabled, position] + ); React.useEffect(() => { if (keyboardDismissMode === 'auto') { @@ -72,9 +81,14 @@ export default function PagerViewAdapter({ } if (indexRef.current !== index) { - pagerRef.current?.setPage(index); + if (animationEnabled) { + pagerRef.current?.setPage(index); + } else { + pagerRef.current?.setPageWithoutAnimation(index); + position.setValue(index); + } } - }, [keyboardDismissMode, index]); + }, [keyboardDismissMode, index, animationEnabled, position]); const onPageScrollStateChanged = ( state: PageScrollStateChangedNativeEvent diff --git a/src/PanResponderAdapter.tsx b/src/PanResponderAdapter.tsx index 3d1964a9..0b11fc9c 100644 --- a/src/PanResponderAdapter.tsx +++ b/src/PanResponderAdapter.tsx @@ -58,6 +58,7 @@ export default function PanResponderAdapter({ onSwipeEnd, children, style, + animationEnabled = false, }: Props) { const { routes, index } = navigationState; @@ -76,27 +77,32 @@ export default function PanResponderAdapter({ const swipeDistanceThreshold = layout.width / 1.75; const jumpToIndex = React.useCallback( - (index: number) => { + (index: number, animate = animationEnabled) => { const offset = -index * layoutRef.current.width; const { timing, ...transitionConfig } = DefaultTransitionSpec; - Animated.parallel([ - timing(panX, { - ...transitionConfig, - toValue: offset, - useNativeDriver: false, - }), - ]).start(({ finished }) => { - if (finished) { - onIndexChangeRef.current(index); - pendingIndexRef.current = undefined; - } - }); - - pendingIndexRef.current = index; + if (animate) { + Animated.parallel([ + timing(panX, { + ...transitionConfig, + toValue: offset, + useNativeDriver: false, + }), + ]).start(({ finished }) => { + if (finished) { + onIndexChangeRef.current(index); + pendingIndexRef.current = undefined; + } + }); + pendingIndexRef.current = index; + } else { + panX.setValue(offset); + onIndexChangeRef.current(index); + pendingIndexRef.current = undefined; + } }, - [panX] + [animationEnabled, panX] ); React.useEffect(() => { @@ -230,7 +236,7 @@ export default function PanResponderAdapter({ nextIndex = currentIndex; } - jumpToIndex(nextIndex); + jumpToIndex(nextIndex, true); }; // TODO: use the listeners diff --git a/src/TabView.tsx b/src/TabView.tsx index 9734440f..59d951bf 100644 --- a/src/TabView.tsx +++ b/src/TabView.tsx @@ -51,6 +51,7 @@ export default function TabView({ style, swipeEnabled = true, tabBarPosition = 'top', + animationEnabled = true, }: Props) { const [layout, setLayout] = React.useState({ width: 0, @@ -86,6 +87,7 @@ export default function TabView({ onSwipeStart={onSwipeStart} onSwipeEnd={onSwipeEnd} onIndexChange={jumpToIndex} + animationEnabled={animationEnabled} style={pagerStyle} > {({ position, render, addEnterListener, jumpTo }) => { diff --git a/src/types.tsx b/src/types.tsx index 164ef37b..dd5ba2ea 100644 --- a/src/types.tsx +++ b/src/types.tsx @@ -53,6 +53,7 @@ export type PagerProps = Omit< > & { keyboardDismissMode?: 'none' | 'on-drag' | 'auto'; swipeEnabled?: boolean; + animationEnabled?: boolean; onSwipeStart?: () => void; onSwipeEnd?: () => void; };