Track pager drag gesture in a worklet
This commit is contained in:
@@ -4,6 +4,11 @@ import PagerView, {
|
|||||||
PagerViewOnPageSelectedEvent,
|
PagerViewOnPageSelectedEvent,
|
||||||
PageScrollStateChangedNativeEvent,
|
PageScrollStateChangedNativeEvent,
|
||||||
} from 'react-native-pager-view'
|
} from 'react-native-pager-view'
|
||||||
|
import Animated, {
|
||||||
|
useEvent,
|
||||||
|
useHandler,
|
||||||
|
useSharedValue,
|
||||||
|
} from 'react-native-reanimated'
|
||||||
|
|
||||||
import {atoms as a, native} from '#/alf'
|
import {atoms as a, native} from '#/alf'
|
||||||
|
|
||||||
@@ -29,6 +34,9 @@ interface Props {
|
|||||||
) => void
|
) => void
|
||||||
testID?: string
|
testID?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const AnimatedPagerView = Animated.createAnimatedComponent(PagerView)
|
||||||
|
|
||||||
export const Pager = forwardRef<PagerRef, React.PropsWithChildren<Props>>(
|
export const Pager = forwardRef<PagerRef, React.PropsWithChildren<Props>>(
|
||||||
function PagerImpl(
|
function PagerImpl(
|
||||||
{
|
{
|
||||||
@@ -43,6 +51,7 @@ export const Pager = forwardRef<PagerRef, React.PropsWithChildren<Props>>(
|
|||||||
) {
|
) {
|
||||||
const [selectedPage, setSelectedPage] = React.useState(0)
|
const [selectedPage, setSelectedPage] = React.useState(0)
|
||||||
const pagerView = React.useRef<PagerView>(null)
|
const pagerView = React.useRef<PagerView>(null)
|
||||||
|
const dragProgress = useSharedValue(selectedPage)
|
||||||
|
|
||||||
React.useImperativeHandle(ref, () => ({
|
React.useImperativeHandle(ref, () => ({
|
||||||
setPage: (index: number) => {
|
setPage: (index: number) => {
|
||||||
@@ -72,21 +81,49 @@ export const Pager = forwardRef<PagerRef, React.PropsWithChildren<Props>>(
|
|||||||
[pagerView],
|
[pagerView],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const handlePageScroll = usePageScrollHandler(
|
||||||
|
{
|
||||||
|
onPageScroll(e: any) {
|
||||||
|
'worklet'
|
||||||
|
const progress = e.offset + e.position
|
||||||
|
dragProgress.value = progress
|
||||||
|
},
|
||||||
|
},
|
||||||
|
[],
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View testID={testID} style={[a.flex_1, native(a.overflow_hidden)]}>
|
<View testID={testID} style={[a.flex_1, native(a.overflow_hidden)]}>
|
||||||
{renderTabBar({
|
{renderTabBar({
|
||||||
selectedPage,
|
selectedPage,
|
||||||
onSelect: onTabBarSelect,
|
onSelect: onTabBarSelect,
|
||||||
})}
|
})}
|
||||||
<PagerView
|
<AnimatedPagerView
|
||||||
ref={pagerView}
|
ref={pagerView}
|
||||||
style={[a.flex_1]}
|
style={[a.flex_1]}
|
||||||
initialPage={initialPage}
|
initialPage={initialPage}
|
||||||
onPageScrollStateChanged={handlePageScrollStateChanged}
|
onPageScrollStateChanged={handlePageScrollStateChanged}
|
||||||
onPageSelected={onPageSelectedInner}>
|
onPageSelected={onPageSelectedInner}
|
||||||
|
onPageScroll={handlePageScroll}>
|
||||||
{children}
|
{children}
|
||||||
</PagerView>
|
</AnimatedPagerView>
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
function usePageScrollHandler(handlers: any, dependencies: any): any {
|
||||||
|
const {context, doDependenciesDiffer} = useHandler(handlers, dependencies)
|
||||||
|
const subscribeForEvents = ['onPageScroll']
|
||||||
|
const {onPageScroll} = handlers
|
||||||
|
return useEvent(
|
||||||
|
event => {
|
||||||
|
'worklet'
|
||||||
|
if (event.eventName.endsWith('onPageScroll')) {
|
||||||
|
onPageScroll?.(event, context)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
subscribeForEvents,
|
||||||
|
doDependenciesDiffer,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user