【问题标题】:React Native slide out panel and scrollviewReact Native 滑出面板和滚动视图
【发布时间】:2018-05-26 15:48:51
【问题描述】:

我正在开发一个带有本机反应的应用程序。我有这个 UI 元素,它类似于 iOS 中的地图,您可以在其中从底部滑动一个面板,在其中有一个可滚动的列表。

对于滑出式面板,我使用了一个名为 rn-sliding-up-panel 的组件。它有几个道具作为事件监听器。例如

<SlidingUpPanel
  allowDragging={/*Boolean*/}
  onDragStart={()=>{}   /*When it is about to be dragged*/}
  onDrag={()=>{} /*When it is being dragged*/}
  onDragEnd={()={} /*When the user is no longer touching the screen*/}
></SlidingUpPanel>

在其中,我有一个&lt;ScrollView&gt;,其中包含来自react-native-elements&lt;List&gt;。据我所知,它只有一个发泄监听器,即:

<ScrollView onScroll={()=>{}}></ScrollView>

我的问题是,在列表上滚动实际上会导致面板关闭(它通过向下滑动关闭)。我通过添加一个状态并在滚动上对其进行修改找到了解决方法:

state = {
  dragPanel: true,
}
/*===========================================*/
<SlidingUpPanel allowDragging={this.state.dragPanel}>
     <ScrollView onScroll={()={ this.setState({dragPanel: false}) }}></ScrollView>
</SlidingUpPanel>

但是,我找不到恢复拖动的方法,而且启动效率也不高。


TL;DR

是否有一种有效的方法可以在 SlidingUpPanel 中实现 ScrollView 而不会发生每个重叠的事件?也许使用类似于function(e){e.preventDefault();} 的东西?

【问题讨论】:

    标签: javascript reactjs user-interface react-native


    【解决方案1】:

    要正确禁用/恢复外部滚动拖动,请执行

    _onGrant() {
      this.setState({ dragPanel: false });
      return true;
    }
    
    _onRelease() {
      this.setState({ dragPanel: true });
    }
    
    constructor(props) {
      super(props);
    
      this._onGrant = this._onGrant.bind(this);
      this._onRelease = this._onRelease.bind(this);
    
      this._panResponder = PanResponder.create({
        onMoveShouldSetPanResponder: this._onGrant,
        onPanResponderRelease: this._onRelease,
        onPanResponderTerminate: this._onRelease,
      });
    }
    
    render() {
      <SlidingUpPanel allowDragging={this.state.dragPanel}>
        <ScrollView
          {...this._panResponder.panHandlers}
        />
      </SlidingUpPanel>
    }
    

    从我找了很久,preventDefault() 是一个纯 web-javascript 的东西,我认为 react-native 中没有 preventDefault

    从文档部分Handling Touchesreact-native 只需使用 javascript 来模拟 Objc (iOS) 和 Java (Android) 事件。

    【讨论】:

    • 感谢您的回答。据我了解,_onGrant() 应该在用户开始滚动时触发,_onRelease() 在用户停止滚动时触发。 this._panResponder 会相应地启动它们。但是,我应该如何将它实现到&lt;ScrollView&gt;?? (也就是说,没有属性名什么的?)
    • @edvilme {...this._panResponder.panHandlers} 完全符合您的描述。那个叫转让道具 zhenyong.github.io/react/docs/transferring-props.html
    • 谢谢。不幸的是,这似乎并不能解决问题。不过它对我有帮助,我在句柄中添加了一个事件侦听器并拒绝拖动所有滚动事件。谢谢!!!
    • 这对我有用。谢谢!但是,如果 ScrollView 中有任何子视图,它们也需要添加相同的 PanResponder。我还必须将 onGrant 方法添加到 PanResponders onStartShouldSetPanResponder 函数,否则它会不稳定。
    【解决方案2】:

    将 minimumDistanceThreshold 属性设置为 50 左右。对于小屏幕来说可能是 30,对于大屏幕来说可能是 50-60。这样做:

    <SlidingUpPanel minimumDistanceThreshold={isSmallScreen ? 30 : 50}>
      <ScrollView style={{flex: 1}}>
      </ScrollView> 
    </SlidingUpPanel>

    【讨论】:

      【解决方案3】:

      答案可能会迟到,但请使用您的滚动视图作为绝对定位并相应地定位它。

      将滚动视图想象成一个弹出对话框,出现在它背后的背景之前。单击背景后,弹出窗口消失。通过让滚动视图在上滑面板前面应用类似的逻辑。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-01-25
        • 1970-01-01
        • 1970-01-01
        • 2016-03-18
        • 1970-01-01
        • 2022-11-30
        • 1970-01-01
        • 2016-01-18
        相关资源
        最近更新 更多