我知道这个问题已经被提出过很多次了,但是我还没有找到其他任何线程上都能正常工作的解决方案(大多数线程几乎没有回复)。
在我的实现中,我有一个ScrollView,它是项目列表的父项,每个项目都有一个panResponder可以侧向轻扫(像火种卡一样)。
我遇到的问题是ScrollView会停止panResponder动画的中期,并优先考虑滚动。
我尝试在scrollEnabled
和onPanResponderGrant
的scrollView上动态切换onPanResponderRelease
,但这不是一个可行的解决方案,因为在panResponder上垂直滚动会触发onPanResponderGrant
,从而禁用滚动。
这是我对panResponder
的实现:
this._panResponder = PanResponder.create({
onStartShouldSetPanResponder: (evt, gestureState) => true,
onStartShouldSetPanResponderCapture: (evt, gestureState) => true,
onMoveShouldSetPanResponder: (evt, gestureState) => false,
onMoveShouldSetPanResponderCapture: (evt, gestureState) => false,
onShouldBlockNativeResponder: (evt, gestureState) => false,
onPanResponderTerminationRequest: () => false,
onPanResponderGrant: (event, gestureState) => {
this.pan.setValue(0);
this.opacity.setValue(0)
this.rotation.setValue(0)
},
onPanResponderMove: (event, gesture) => {
this.pan.setValue(gesture.dx)
this.rotation.setValue(gesture.dx)
this.opacity.setValue(gesture.dx)
},
onPanResponderRelease: (event, gestureState) => {
if(gestureState.dx < -SWIPE_THRESHOLD){
this.removeCard()
} else {
this.resetPosition()
}
}
});
这是呈现每个可刷卡的FlatList:
<FlatList
data={this.state.cards}
keyExtractor={item => item.id}
renderItem={({ item }) => (
<DataCard
type={item.type}
name={item.name}
/>
)}
/>
此后,我将ScrollView
换成了FlatList
,希望能神奇地解决这个问题,但没有运气。
此功能可在iOS上完美运行,但问题仍然是android。
这似乎是一个非常普遍的问题,没有具体解决方案。我希望通过发布此内容来实现此目的。
谢谢!
答案 0 :(得分:1)
我知道已经很晚了,但是我希望这个答案可以帮助其他像我一样遇到同样问题的人。 当两个不同的父组件试图停止动画时,PanResponder似乎不太支持(在这种情况下,您在ScrollView中有一个FlatList)
对我有用的解决方案是将FlatList的scrollEnabled设置为false (当您位于另一个滚动视图中时,它仍将起作用)这样,平移响应器将不得不处理ScrollView
此外-不要忘记设置“ onPanResponderTerminate()”,以使组件返回到初始位置,并像这样将父元素(ScrollView)的scrollable = true返回:
onPanResponderTerminate: () => {
this.props.changeScrollable(true);
this.resetPosition();
},
我真的希望这已经足够清楚了,并且可以对某人有所帮助!
答案 1 :(得分:1)
在这里很晚,但是万一将来有人遇到这个问题,我发现的解决方案就是将canCancelContentTouches
的{{1}}属性设置为ScrollView
。这样可以使false
事件在PanResponder
内继续存在。
ScrollView
注意:此实现将阻止完全滚动<ScrollView canCancelContentTouches={false}>
,您可以在此处使用状态来帮助您:
ScrollView
答案 2 :(得分:0)
尝试在onShouldBlockNativeResponder: () => false
配置对象中使用PanResponder.create
答案 3 :(得分:0)
我也在为这个问题而苦苦挣扎,我不知道这是否是最好的方法,但是它为我工作(经过大量的浪费时间)
this._panResponder = PanResponder.create({
onStartShouldSetPanResponder: (evt, gestureState) => false,
onStartShouldSetPanResponderCapture: (evt, gestureState) => false,
onMoveShouldSetPanResponder: (evt, gestureState) => false,
onMoveShouldSetPanResponderCapture: (evt, gestureState) => false,
onShouldBlockNativeResponder: () => false,
onPanResponderGrant: (evt, gestureState) => {
if (this.state.isPanAlive) {
this.doSomething()
}
return false
},
});
我放到ScrollView
里面,因为我遇到了View
的滚动问题
<ScrollView {...this._panResponder.panHandlers}>
答案 4 :(得分:0)
尝试一下:
onMoveShouldSetPanResponder: (_, gestureState) => {
return Math.abs(gestureState.dx) > 10;
},
之所以可行,是因为直到变化量达到10点左右时, PanResponder 才得到控制。该值是任意的。