【问题标题】:In React Native, is it possible to detect a swipe vs a tap in Pan Responder's onStartShouldSetPanResponder?在 React Native 中,是否可以在 Pan Responder 的 onStartShouldSetPanResponder 中检测到滑动与轻击?
【发布时间】:2017-08-08 16:52:49
【问题描述】:

现在,我在我的onStartShouldSetPanResponder 中返回一个true,因此 PanResponder 想要处理水龙头和平移。有什么办法可以将它限制在平底锅上,因为我想要一个TouchableHighlight 来处理它? (我知道手势响应器应该同时处理两者,但“平移”响应器处理水龙头似乎很奇怪)

由于手势刚刚开始,dx/dyonStartShouldSetPanResponder 中为 0。有什么方法可以检测是否是点击的开始并返回 false,如果是的话?

或者我应该只检测OnPanResponderRelease 中的点击还是平移?

【问题讨论】:

    标签: javascript react-native


    【解决方案1】:

    我能够通过 onMoveShouldSetPanResponder 方法完成此操作,如下所示:

    onMoveShouldSetPanResponder: (evt, gestureState) => {
        return Math.abs(gestureState.dx) >= 1 || Math.abs(gestureState.dy) >= 1
    }
    

    如果 x 或 y 移动大于 1,则返回 true。然后为了检测点击,我必须将包含 panHandlers 的所有内容都包含在我的视图中,并带有一个可触摸的元素。这是一个完整的工作示例:

    import React, { Component } from 'react';
    import { TouchableOpacity, Animated, PanResponder, Text, View, StyleSheet } from 'react-native';
    import Constants from 'expo-constants';
    
    export default function App() {
      return (
        <View>
          <CircleTapExample/>
        </View>
      );
    }
    
    class CircleTapExample extends Component {
        constructor(props) {
            super(props)
            this.position = new Animated.ValueXY({ x: 0, y: 0 });
            this.panResponder = PanResponder.create({
                onMoveShouldSetPanResponder: (evt, gestureState) => {
                  return Math.abs(gestureState.dx) >= 1 || Math.abs(gestureState.dy) >= 1
                },
                onPanResponderMove: (evt, gestureState) => {
                    console.log("I was moved")
                    this.position.setValue({ x: gestureState.moveX, y: gestureState.moveY })
                },
            });
        }
        
        circleTapped() {
            // Do something here when tapped
            console.log("I was tapped")
        }
        
        render() {
            return (
                <Animated.View style={[styles.container, { ...this.position.getLayout() }]} {...this.panResponder.panHandlers}>
                    <TouchableOpacity onPress={() => this.circleTapped()} style={{ flex: 1 }}>
                        <View style={styles.circle} />
                    </TouchableOpacity>
                </Animated.View>
            )
        }
    }
    
    const styles = StyleSheet.create({
      container: {
          width: 75,
          height: 75,
          bottom: 5,
          left: 5,
          position: 'absolute'
      },
      circle: {
          width: 75,
          height: 75,
          borderRadius: 40,
          backgroundColor: 'red'
      }
    });
    

    <div data-snack-id="YskU-lxRe" data-snack-platform="web" data-snack-preview="true" data-snack-theme="light" style="overflow:hidden;background:#F9F9F9;border:1px solid var(--color-border);border-radius:4px;height:505px;width:100%"></div>
    <script async src="https://snack.expo.dev/embed.js"></script>

    【讨论】:

      【解决方案2】:

      panResponder 有两个事件:

      • onStartShouldSetPanResponder(捕获)
      • onMoveShouldSetPanResponder(捕获)

      我只能通过删除 onStartShouldSetPanResponderCapture 来解决这个问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-02-01
        • 2019-07-31
        • 1970-01-01
        • 2017-06-22
        • 1970-01-01
        相关资源
        最近更新 更多