Определите направление смахивания с помощью React Native Gesture Handler и Reanimated
Мы уже разработали swiper с использованием React Native PanResponder (до того, как кто-то прокомментирует) - мы не можем использовать здесь никакую другую библиотеку swiper. В разработанном нами свайпере мы сталкиваемся с проблемой, когда пользователь завершает свайп (то есть отпускает панорамирование), возникает задержка при запуске весенней анимации.
Поэтому, чтобы исправить это, мы пытаемся перейти от React Native Animated API к Reanimated Libary, что могло бы решить проблему лагов, с которыми сталкивается пользователь.
Но при разработке с помощью React Native Gesture Handler (PanGestureHandler) и Reanimated Library мы не можем определить направление смахивания в обработчике жестов.
Я добавляю часть кода, которую мы использовали для определения направления смахивания в PanResponder.
onPanMoving = (evt, {dx}) => {
this.draggedEnd = dx < -this.swipeThreshold; //You are moving towards right screen
this.draggedStart = dx > this.swipeThreshold; //You are moving towards left screen
}
Как видите, определить направление при движении панорамирования в PanResponder было очень просто.
Вот проблема с Gesture Handler,
Я не могу обнаружить смахивание при активном состоянии жеста
Я уже искал проблемы в Gesture Handler и нашел это.
В этой проблеме было предложено два обходных пути
- Первый - от Sonaye, который имеет два обработчика и определяет направление смахивания в onHandlerStateChange для обоих обработчиков, что не помогло при использовании reanimated, поскольку оно устанавливает направление смахивания только при изменении состояния обработчиков.
- Второй один является Satya, который на самом деле обнаруживает красть, когда государство является активным, но он использует translationX свойство, свойство translationX может также негативно для нас и может двигаться в любом направлении, совпадающем с Swiper.
Оба пути не решают нашу проблему.
Есть ли другой способ найти направление с помощью PanGestureHandler и Reanimated. Я попытался использовать PanResponder с Reanimated со значением dx, но в итоге появилось сообщение об ошибке, т.е. свойства nativeEvent поддерживаются только потому, что dx взят из параметра gestureState из PanResponder.
Примечание. Мы не можем использовать FlingGestureHandler и Swipeables, потому что нам нужно найти направление в Fling по-прежнему onHandlerStateChange, а Swipeables не использует Reanimated.
4 ответа
Вы можете определить направление, проведя по горизонтали через свойство
velocityX
Пример :
const handleGesture = (evt) => {
const { nativeEvent } = evt;
if (nativeEvent.velocityX > 0) {
console.log('Swipe right');
} else {
console.log('Swipe left');
}
};
return (
<PanGestureHandler onGestureEvent={handleGesture}>
// child component
</PanGestureHandler>
);
Для тех, кто хочет использовать двойной жест вертикального или горизонтального броска, вот решение:
Сначала вы должны инициализировать
stateHandlers
для нужного вам направления. В моем случае я пытался реализовать вертикальный
flingGestureHandler
.
const onDownFlingHandlerStateChange = ({
nativeEvent,
}: FlingGestureHandlerStateChangeEvent) => {
if (nativeEvent.oldState === State.ACTIVE) {
progressHeight.value = withTiming(COLLAPSED_HEIGHT, {
duration: ANIMATION_DURATION,
});
}
};
const onUpFlingHandlerStateChange = ({
nativeEvent,
}: FlingGestureHandlerStateChangeEvent) => {
if (nativeEvent.oldState === State.ACTIVE) {
progressHeight.value = withTiming(
DEVICE_HEIGHT - TOP_PADDING_FOR_EXPANDED,
{
duration: ANIMATION_DURATION,
},
);
}
};
а затем вам нужно привязать эти обработчики к 2
FlingGestureHandler
компонент RNGH
<FlingGestureHandler
onHandlerStateChange={onUpFlingHandlerStateChange}
onEnded={() => {
onPressChecklistIcon();
}}
direction={Directions.UP}>
<FlingGestureHandler
direction={Directions.DOWN}
onEnded={() => {
onPressChecklistIcon();
}}
onHandlerStateChange={onDownFlingHandlerStateChange}>
<Animated.View style={[styles.container, reanimatedStyle]}>
<View style={styles.closerContainer}>
<View style={styles.closer} />
</View>
{renderChecklistContent()}
</Animated.View>
</FlingGestureHandler>
</FlingGestureHandler>
Используйте свойство translationX, а не свойство Velocity для nativeEvent:
В моем случае я использовал для определения направления. У меня это сработало.