React 原生手势处理程序会在 Android 上覆盖,但不会在 ios 上覆盖

问题描述 投票:0回答:2

我想知道为什么如果我用手势检测器包装滚动视图,我的反应本机,我无法在 Android 上滚动但可以在 ios 上滚动。我想知道如何让我的滚动视图在 Android 上工作。

谢谢!

const gest = Gesture.Pan().onUpdate((e) => {...})

return(
 <GestureDetector gesture={roomGestureTV}>
 <ScrollView ... />
</GestureDetector>
)
react-native
2个回答
1
投票

这里是一个 Snack,展示了如何使用 PanGesture 包装 ScrollView(Snack 或下面以供将来参考)。我已经在 Galaxy S9 (Android) 和 iPhone 13(真实版和模拟器)上测试了代码。

一些注意事项(先看零食!):

  • Android 和 IOS 手势的行为不同,因为它们(react-native-gesture-handler)必须在 Android 上实现自定义解决方案,但不能在 IOS 上实现。在 Android 上,平移手势会取消 ScrollView 手势,但在 IOS 上,ScrollView 会取消 PanGesture。在这两种情况下,平移手势和滚动手势不能同时开箱即用。
  • 使用 createNativeWrapper 而不是手势处理程序中的 ScrollView。虽然手势处理程序中的 ScrollView 可以工作,但基于 ScrollView 构建的其他组件则不能(例如 FlatLists)。为了使用 FlatList 而不是 ScrollView,请在 createNativeWrapper 中将 ScrollView 与 FlatList 交换
  • 库 (
  • Source) 不再积极支持 createNativeWrapper。但是,new/old本机手势组件不适用于此用例(至少对我来说)。这可能是一个错误,可能会在新版本中修复。
  • 请注意,ScrollView 的并发处理程序不限于一种手势,还可以接受多种手势。例如。滚动时可以进行平移和捏合手势。

参考代码


    import React, { useRef } from 'react';
    import { Text, View, ScrollView } from 'react-native';
    import Animated, {
      useDerivedValue,
      useSharedValue,
      useWorkletCallback,
    } from 'react-native-reanimated';
    import {
      createNativeWrapper,
      GestureHandlerRootView,
      Gesture,
      GestureDetector,
    } from 'react-native-gesture-handler';
    import ReText from './components/ReText';

    /**
     * Gesture states 
     * (see https://docs.swmansion.com/react-native-gesture-handler/docs/under-the-hood/states-events)
     */
    const STATES = {
      0: 'UNDETERMINED',
      1: 'FAILED',
      2: 'BEGAN',
      3: 'CANCELLED',
      4: 'ACTIVE',
      5: 'END',
    };

    const CustomScrollComponent = createNativeWrapper(ScrollView)

    export default function App() {
      const panRef = useRef(null);
      const scrollRef = useRef(null);

      // Log values
      const touchPosition = useSharedValue({ x: null, y: null });
      const touchPositionX = useDerivedValue(() => {
        return `x: ${touchPosition.value.x}`;
      });
      const touchPositionY = useDerivedValue(() => {
        return `y: ${touchPosition.value.y}`;
      });

      const state = useSharedValue([STATES[0], 'null', 'null']);
      const stateString = useDerivedValue(() => {
        return `${state.value[0]}\n${state.value[1]}\n${state.value[2]}`;
      });

      const appendState = useWorkletCallback((arr, value) => {
        return [value].concat(arr.slice(0, 2));
      }, []);

      const panGesture = Gesture.Pan()
        .onBegin((e) => {
          state.value = appendState(state.value, STATES[e.state]);
        })
        .onStart((e) => {
          state.value = appendState(state.value, STATES[e.state]);
        })
        .onUpdate((e) => {
          if (state.value[0] !== STATES[e.state]) {
            state.value = appendState(state.value, STATES[e.state]);
          }
          touchPosition.value = { x: e.absoluteX, y: e.absoluteY };
        })
        .onEnd((e) => {
          state.value = appendState(state.value, STATES[e.state]);
        })
        .onFinalize((e) => {
          state.value = appendState(state.value, STATES[e.state]);
          touchPosition.value = { x: null, y: null };
        })
        .simultaneousWithExternalGesture(scrollRef)
        .withRef(panRef);

      return (
        <GestureHandlerRootView style={{ flex: 1 }}>
          <View style={{ flex: 1 }}>
            {/** Logger */}
            <View style={{ padding: 16, height: 180, justifyContent: 'flex-end' }}>
              <ReText text={touchPositionX} />
              <ReText text={touchPositionY} />
              <Text>Gesture States (New -> Old):</Text>
              <ReText text={stateString} />
            </View>
            {/** ScrollView with pan gesture */}
            <GestureDetector gesture={panGesture}>
              <Animated.View style={{ flex: 1 }}>
                <CustomScrollComponent
                  disallowInterruption={false}
                  scrollEnabled={true}
                  ref={scrollRef}
                  style={{ flex: 1 }}
                  simultaneousHandlers={panRef}>
                  <Text>
                    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed
                    diam nonumy eirmod tempor invidunt ut labore et dolore magna
                    aliquyam erat, sed diam voluptua. At vero eos et accusam et
                    justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea
                    takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum
                    dolor sit amet, consetetur sadipscing elitr, sed diam nonumy
                    eirmod tempor invidunt ut labore et dolore magna aliquyam erat,
                    sed diam voluptua. At vero eos et accusam et justo duo dolores
                    et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus
                    est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet,
                    consetetur sadipscing elitr, sed diam nonumy eirmod tempor
                    invidunt ut labore et dolore magna aliquyam erat, sed diam
                    voluptua. At vero eos et accusam et justo duo dolores et ea
                    rebum. Stet clita kasd gubergren, no sea takimata sanctus est
                    Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet,
                    consetetur sadipscing elitr, sed diam nonumy eirmod tempor
                    invidunt ut labore et dolore magna aliquyam erat, sed diam
                    voluptua. At vero eos et accusam et justo duo dolores et ea
                    rebum. Stet clita kasd gubergren, no sea takimata sanctus est
                    Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet,
                    consetetur sadipscing elitr, sed diam nonumy eirmod tempor
                    invidunt ut labore et dolore magna aliquyam erat, sed diam
                    voluptua. At vero eos et accusam et justo duo dolores et ea
                    rebum. Stet clita kasd gubergren, no sea takimata sanctus est
                    Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet,
                    consetetur sadipscing elitr, sed diam nonumy eirmod tempor
                    invidunt ut labore et dolore magna aliquyam erat, sed diam
                    voluptua. At vero eos et accusam et justo duo dolores et ea
                    rebum. Stet clita kasd gubergren, no sea takimata sanctus est
                    Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet,
                    consetetur sadipscing elitr, sed diam nonumy eirmod tempor
                    invidunt ut labore et dolore magna aliquyam erat, sed diam
                    voluptua. At vero eos et accusam et justo duo dolores et ea
                    rebum. Stet clita kasd gubergren, no sea takimata sanctus est
                    Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet,
                    consetetur sadipscing elitr, sed diam nonumy eirmod tempor
                    invidunt ut labore et dolore magna aliquyam erat, sed diam
                    voluptua. At vero eos et accusam et justo duo dolores et ea
                    rebum. Stet clita kasd gubergren, no sea takimata sanctus est
                    Lorem ipsum dolor sit amet. gubergren, no sea takimata sanctus
                    est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet,
                    consetetur sadipscing elitr, sed diam nonumy eirmod tempor
                    invidunt ut labore et dolore magna aliquyam erat, sed diam
                    voluptua. At vero eos et accusam et justo duo dolores et ea
                    rebum. Stet clita kasd gubergren, no sea takimata sanctus est
                    Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet,
                    consetetur sadipscing elitr, sed diam nonumy eirmod tempor
                    invidunt ut labore et dolore magna aliquyam erat, sed diam
                    voluptua. At vero eos et accusam et justo duo dolores et ea
                    rebum. Stet clita kasd gubergren, no sea takimata sanctus est
                    Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet,
                    consetetur sadipscing elitr, sed diam nonumy eirmod tempor
                    invidunt ut labore et dolore magna aliquyam erat, sed diam
                    voluptua. At vero eos et accusam et justo duo dolores et ea
                    rebum. Stet clita kasd gubergren, no sea takimata sanctus est
                    Lorem ipsum dolor sit amet.
                  </Text>
                </CustomScrollComponent>
              </Animated.View>
            </GestureDetector>
          </View>
        </GestureHandlerRootView>
      );
    }



0
投票

如果您特别指示 RNGH Gesture.native,将会有所帮助。是

const gest = Gesture.Pan().onUpdate((e) => {...})
const native = Gesture.Native();

return (
  <GestureDetector gesture={Gesture.Simultaneous(pan, native)}>
    <Animated.ScrollView ...
  </GestureDetector>
);

ScrollView 应该是 GestureHandler 的直接子级。

© www.soinside.com 2019 - 2024. All rights reserved.