React Native:在Android上损坏的scrollview中使用panResponder

时间:2018-08-06 10:16:27

标签: android react-native

我知道这个问题已经被提出过很多次了,但是我还没有找到其他任何线程上都能正常工作的解决方案(大多数线程几乎没有回复)。

在我的实现中,我有一个ScrollView,它是项目列表的父项,每个项目都有一个panResponder可以侧向轻扫(像火种卡一样)。

我遇到的问题是ScrollView会停止panResponder动画的中期,并优先考虑滚动。

我尝试在scrollEnabledonPanResponderGrant的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。

这似乎是一个非常普遍的问题,没有具体解决方案。我希望通过发布此内容来实现此目的。

谢谢!

5 个答案:

答案 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 才得到控制。该值是任意的。