[英]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.