简体   繁体   English

如何获取PanResponder相对于父视图的当前触摸坐标?

[英]How to get current touch coordinates of PanResponder relative to parent view?

Using React-Native, I'm trying to capture swipe events on a list view item. 使用React-Native,我正在尝试捕获列表视图项上的滑动事件。 Everything works well but i'm having difficulties acquiring the current coordinate of the touch gesture, relative to the list view item. 一切都运作良好,但相对于列表视图项,我很难获取触摸手势的当前坐标。

In my _handlePanResponderMove , I use the following snippet: 在我的_handlePanResponderMove ,我使用以下代码段:

let relativeY = event.nativeEvent.locationY;

Unfortunately, the Y coordinate I'm getting is relative to the "child view" the swipe occurred on, and not relative to the list view item (as I was expecting, since I attached the PanResponder to the list view item) 不幸的是,我得到的Y坐标是相对于滑动发生的“子视图”,而不是相对于列表视图项(正如我所料,因为我将PanResponder附加到列表视图项)

How can I get the gestures' Y coordinate relative to the list view parent? 如何获得相对于列表视图父级的手势Y坐标?

Set the child view to pointerEvents="none" like so: 将子视图设置为pointerEvents="none"如下所示:

  <View pointerEvents="none">
        ...
  </View>

That way, the event you receive on your event.nativeEvent.locationY will not take into account the child view coordinates at all, and that will do exactly what you want. 这样,您在event.nativeEvent.locationY上收到的事件将根本不考虑子视图坐标,这将完全符合您的要求。

Try to add a ref to the child and then measure its relative distances. 尝试为孩子添加一个ref,然后测量它的相对距离。 This code represents the wrapper with a widget (child component). 此代码表示具有widget (子组件)的包装器。 It works for me! 这个对我有用! Notice that this.refs.self.measure is trigger after a setTimeout, it was not working without it. 请注意, this.refs.self.measure是在setTimeout之后触发的,没有它就无法工作。 Could be a bug of measure or that the references are not updated after an instant. 可能是一个测量错误或者在瞬间之后没有更新引用。

import React, { Component } from 'react'
import TimerMixin from 'react-timer-mixin'
import {
  StyleSheet,
  View,
  TouchableHighlight,
  Text,
  Alert,
  PanResponder,
  Animated,
  Dimensions } from 'react-native'
import BulbWidget from './bulb-widget'

const COLUMNS = 3

export default class Widget extends Component {
  constructor (props) {
    super()
    this.state = {
      pan: new Animated.ValueXY(),
      touches: 1
    }
    this.panResponder = PanResponder.create({
      onStartShouldSetPanResponder: () => true,
      onPanResponderMove: Animated.event([null, {
        dx: this.state.pan.x,
        dy: this.state.pan.y
      }]),
      onPanResponderRelease: (e, gesture) => {
        this.state.pan.flattenOffset()
        this._setPosition(gesture)
        Animated.spring(
          this.state.pan,
          {toValue: {x: 0, y: 0}}
        ).start()
      },
      onPanResponderGrant: (e, gestureState) => {
        this.state.pan.setOffset({x: this.state.pan.x._value, y: this.state.pan.y._value})
        this.state.pan.setValue({x: 0, y: 0})
        this._onPressWidget()
      }
    })
  }

  render () {
    let styleWidget = {}
    this.props.type === 'L' ? styleWidget = styles.widgetL : styleWidget = styles.widget

    return (
      <View ref='self' style={this.state.placed}>
        <Animated.View {...this.panResponder.panHandlers}
          style={[this.state.pan.getLayout(), styleWidget]} >
            <BulbWidget ref='child'/>
        </Animated.View>
      </View>
    )
  }

  componentDidMount () {
    // Print component dimensions to console
    setTimeout(() => {
      this.refs.self.measure((fx, fy, width, height, px, py) => {
        console.log('Component width is: ' + width)
        console.log('Component height is: ' + height)
        console.log('X offset to frame: ' + fx)
        console.log('Y offset to frame: ' + fy)
        this.offset = { fx, fy, width, height }
      })
    }, 0)
  }

  _onPressWidget () {
    this.refs.child.onPressAction()
    this.setState({touches: this.state.touches + 1})
    TimerMixin.setTimeout(() => {
      this.setState({ touches: 1 })
      console.log('Reset')
    }, 1000)

    if (this.state.touches === 2) {
      this.setState({touches: 1})
    }
  }

  _setPosition (gesture) {
    const dx = gesture.moveX - gesture.x0
    const dy = gesture.moveY - gesture.y0

    const { width, height } = this.offset
    const x = Math.abs(this.offset.fx + dx)
    const y = Math.abs(this.offset.fy + dy)

    const idTo = (Math.floor(x / width) + Math.floor(y / height) * COLUMNS)
    this.props.setPosition(gesture, this.props.idx, idTo)
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM