在React-Native中滚动一次调用函数

时间:2018-03-30 09:22:25

标签: android ios animation react-native scrollview

我正在构建一个应用程序,其中有一个名为<SearchBar />的可实现标头,其具有支持isCollaped(值可以为true或false),用于打开和关闭容器,以及{{1 (下面的截图,抱歉没有英文文本)。 应用的屏幕截图:

Case when isCollaped == false

Case when isCollaped == true

我想在开始滚动<ScrollView />时展开<SearchBar />,因此我将<ScrollView />的值设置为true,并且它有效,但由于isCollaped每隔200毫秒调用<ScrollView />,并且在释放手指后滚动动画不停止,当我尝试通过按下它再次打开onScroll时,如果滚动动画仍处于活动状态,我会得到一个非常错误的动画,再次折叠<SearchBar />

这部分代码在按下时会调整SearchBar的大小:

<SearchBar />

这是collapseSearchBar = () => { this.setState({ searchBarCollapsed: !this.state.searchBarCollapsed, }); };

<SearchBar/>

这是<SearchBar isCollapsed={this.state.searchBarCollapsed} onCollapse={this.collapseSearchBar} onSearch={this.search} /> 的代码:

<ScrollView />

我的问题是:当用户滑动时,我怎样才能进行一次<ListView ref='mainScrollView' dataSource={this.state.dataSource} renderRow={(rowData) => { return this._renderRow(rowData, this.props.navigation); }} onScroll={() => { if (!this.state.searchBarCollapsed) { this.setState({ searchBarCollapsed: true }); } }} /> 调用<ScrollView />,而不是所有时间(每200毫秒,动画开始后约3秒),动画处于活动状态。

2 个答案:

答案 0 :(得分:0)

您可以使用scrollEventThrottle道具来设置scroll事件的触发频率。

  

<强> scrollEventThrottle

     

它控制滚动时触发滚动事件的频率   (以ms为单位的时间间隔)。数字越小,精度越高   跟踪滚动位置的代码,但可以导致滚动   由于发送的信息量导致的性能问题   这座桥。您不会注意到设置值之间的差异   当JS运行循环同步到屏幕刷新率时,在1到16之间。   如果您不需要精确滚动位置跟踪,请设置此值   更高以限制通过网桥发送的信息。该   默认值为零,这会导致发送滚动事件   每次滚动视图时只会执行一次。

但我认为这不会解决你的问题。您可以做些什么来设置第二个状态值(类似isAnimating ),并在设置标题动画之前检查它。动画结束后,您可以将其设置为false。

示例

<ListView
      ref='mainScrollView'
      dataSource={this.state.dataSource}
      renderRow={(rowData) => {
          return this._renderRow(rowData, this.props.navigation);
      }}
      onScroll={() => {
        if (!this.state.searchBarCollapsed) {
          this.setState({
            searchBarCollapsed: true,
            isAnimating: true
          });
        }
      }}
/>
collapseSearchBar = () => {
   this.interval = setInterval(() => {
     if (this.state.isAnimating === false) {
       this.setState({
         searchBarCollapsed: !this.state.searchBarCollapsed,
         isAnimating: true
       });
       clearInterval(this.interval);
       this.interval = null;
     }
   }, 100)
};

答案 1 :(得分:0)

就我而言,我必须在向上滚动一次和向下滚动一次时为视图设置动画。基本上,它就像在向下滚动时显示视图并在向上滚动时隐藏它一样。由于在滚动时多次调用函数,因此在视图中会产生闪烁效果。所以我创建了一个状态'scrollDown)。

const [scrollDown, setScrollDown] = useState(true)

在我的情况下,最初 scrollDown 将为真,表明用户将首先向下滚动。动画会执行,因为它是真,它也会更新自己为假,所以下次动画不会执行。当然,!scrollDown 会给出 true 但那些代码不会执行,因为它们是向上滚动的。因此,一旦用户向上滚动,scrollDown 值将更新并遵循相同的逻辑。

const _toogleNavigationBtn = (event) => {
    const currentOffset = event.nativeEvent.contentOffset.y;

    if(scrollDown)
        if(currentOffset > offset && offset > 0 ){
                setScrollDown(prevState => !prevState)
                Animated.timing(navigationBtnY,{
                        toValue: 50,
                        duration: 700,
                        easing: Easing.out(Easing.exp)
                    }).start();
        }

    const contentSize = parseInt(event.nativeEvent.contentSize.height)
    const scrolledSize = parseInt(currentOffset + event.nativeEvent.layoutMeasurement.height)
    if(!scrollDown)
        if(offset === 0 || currentOffset < offset || contentSize == scrolledSize){
            setScrollDown(prevState => !prevState)
            Animated.timing(navigationBtnY,{
                        toValue: 0,
                        duration: 700,
                        easing: Easing.out(Easing.exp)
                    }).start();
        }


    setOffset(prevState => currentOffset)
}