React Native嵌套ScrollView锁定

时间:2015-04-20 19:00:47

标签: javascript react-native

我试图在React Native中嵌套ScrollViews;带有嵌套垂直滚动的水平滚动。

以下是一个例子:

var Test = React.createClass({
    render: function() {
        return (
            <ScrollView
                style={{width:320, height:568}}
                horizontal={true}
                pagingEnabled={true}>

                {times(3, (i) => {
                    return (
                        <View style={{width:320, height:568}}>

                            <ScrollView>
                                {times(20, (j) => {
                                    return (
                                        <View style={{width:320, height:100, backgroundColor:randomColor()}}/>
                                    );
                                })}
                            </ScrollView>

                        </View>
                    );
                })}

            </ScrollView>
        );
    },
});

AppRegistry.registerComponent('MyApp', () => Test);

外部卷轴可以完美地工作,但是当它在移动时触摸它时,内部卷轴会粘住。我的意思是:如果你滚动,抬起你的手指并再次触摸它同时它仍然以动量移动,它会停止并且根本不会对触摸动作做出反应。要滚动更多,您必须抬起手指再次触摸。

这是如此可重复,感觉与手势响应器有关。

有没有人见过这个问题?

我怎么会开始调试这个?有没有办法看到什么回应触摸,授予和释放,什么时候?

感谢。

更新:

看起来它是响应者系统,通过在内部和外部滚动条上放置onResponderMove个侦听器:

<ScrollView 
    onResponderMove={()=>{console.log('outer responding');}}
    ...

    <ScrollView
        onResponderMove={()=>{console.log('inner responding');}}>
        ...

很明显,外部ScrollView正在抓住控制权。我想,问题是如何在尝试垂直滚动时阻止外部滚动条控制?为什么只有在您尝试滚动已经移动的内部ScrollView时才会发生这种情况?

5 个答案:

答案 0 :(得分:8)

在内部响应器中,尝试设置:

onPanResponderTerminationRequest: () => false

答案 1 :(得分:6)

@IlyaDoroshin和@David Nathan的答案为我指明了正确的方向,但是我必须用一种可触摸的而不是所有东西都可以触摸的方式将每个内容包装在滚动视图中。

$_SERVER['AUTH_USER'] = 'someUser';
$I->amOnPage('some-route'); // this page redirects to autologin action where $_SERVER is used to get the user logged.

答案 2 :(得分:5)

修改node_modules/react-native/Libraries/Components/ScrollResponder.js:第136行(参见更新):

scrollResponderHandleScrollShouldSetResponder: function(): boolean {
    return this.state.isTouching;
},

更新:我发现滚动视图当前是否为动画并希望成为响应者,然后它将拒绝。 ScrollResponder.js中的第189行。所以我修改了340行,它对我有用:

scrollResponderIsAnimating: function(): boolean {
  // var now = Date.now();
  // var timeSinceLastMomentumScrollEnd = now - this.state.lastMomentumScrollEndTime;
  // var isAnimating = timeSinceLastMomentumScrollEnd < IS_ANIMATING_TOUCH_START_THRESHOLD_MS ||
  //   this.state.lastMomentumScrollEndTime < this.state.lastMomentumScrollBeginTime;
  // return isAnimating;
    return false;
},

您可以在此处看到:https://github.com/facebook/react-native/issues/41

答案 3 :(得分:4)

在Android上为我修复嵌套ScrollView的可滚动内容:

<ScrollView>
  ...
  <ScrollView horizontal>
    <TouchableWithoutFeedback>
      { /* your scrollable content goes here */ }
    </TouchableWithoutFeedback>
  </ScrollView>
</ScrollView>

答案 4 :(得分:3)

如果您使用的是RN> 56.0,只需将此道具添加到滚动视图中即可:

<ScrollView nestedScrollEnabled = {true}>
 ......
  <ScrollView nestedScrollEnabled = {true}>
    .....
  </ScrollView>
</ScrollView>

那是唯一为我工作的人。