react-native scrollView 中部分有用事件

本文介绍如何在React Native中利用onScrollEndDrag方法优化滑动监听,并通过scrollEventThrottle属性减少不必要的滚动事件触发,提高应用性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在scrollView 中有个onScroll prop,可以实时监听滑动事件,配合属性scrollEventThrottle 来使用,当scrollEventThrottle属性值设置比较低时,对位置比较敏感,会多次触发onScroll,为了保证onScroll只触发一次可以将scrollEventThrottle值调高些,如scrollEventThrottle={200},该属性默认为0,

可惜scrollEventThrottle只在IOS中有效,而在android中无效,想要事项滑屏手势向下或向上滑动时滑动到一定距离的位置,显然onScroll在android是无法使用的,因为它会多次触发onScroll,导致滑动指定位置有误,而且影响性能。

  在android源码中有个方法:onScrollEndDrag ,该方法是当手势离开屏幕时触发,不知为何在当前官方文档(0.28版本上)上么有记录,而在源码中有该方法的注册:

public static Map createExportedCustomDirectEventTypeConstants() {
    return MapBuilder.builder()
        .put(ScrollEventType.SCROLL.getJSEventName(), MapBuilder.of("registrationName", "onScroll"))
        .put(ScrollEventType.BEGIN_DRAG.getJSEventName(), MapBuilder.of("registrationName", "onScrollBeginDrag"))
        .put(ScrollEventType.END_DRAG.getJSEventName(), MapBuilder.of("registrationName", "onScrollEndDrag"))
        .put(ScrollEventType.ANIMATION_END.getJSEventName(), MapBuilder.of("registrationName", "onScrollAnimationEnd"))
        .put(ScrollEventType.MOMENTUM_BEGIN.getJSEventName(), MapBuilder.of("registrationName", "onMomentumScrollBegin"))
        .put(ScrollEventType.MOMENTUM_END.getJSEventName(), MapBuilder.of("registrationName", "onMomentumScrollEnd"))
        .build();
  }


故想要实现滑动时滑动指定距离,如一屏距离,可以通过该方法来实现:

<ScrollView
        style={styles.container}
        ref={(scrollView) => { _scrollView = scrollView; }}
        scrollEventThrottle={200}
        pagingEnabled={true}
        // onScroll={(event)=> {
        //    this._pushEvent(event);
        //    }
        // }
        onScrollEndDrag={(event)=>{
          this._handleEndDrag(event,_scrollView);
        }
      }


对应_handleEndDrag方法具体如下(只有三个组件位置,且组件高度为屏幕高度,故当我在最顶部时向上滑动不改变位置,在最低部时向下滑动不改变位置):

  _handleEndDrag:function(event:Object,_scrollView){
    var endposition=event.nativeEvent.contentOffset.y;//取得拖拉后的位置
    var stepheight=this.state.dimensionsY;
  //  alert(endposition+","+this.state.positionY);
    var flag=endposition-this.state.positionY;
    if(flag>0){
      var newpositionY=this.state.positionY+stepheight;
      if(newpositionY>=(2*stepheight)){
        newpositionY=2*stepheight;
      }
      _scrollView.scrollTo({y:newpositionY});
       this.setState({positionY:newpositionY});
    }else if(flag<0){
      let newpositionY=this.state.positionY-stepheight;
      _scrollView.scrollTo({y:newpositionY});
      this.setState({positionY:newpositionY});
    }
  }


在 getInitialState(){
    //  var {height,width}=Dimensions.get('window');
     return({
       positionY:0,//初始屏幕所在位置
       dimensionsY:Dimensions.get('window').height//取得手机屏幕高度
     })
   },


Dimensions的使用,需要

import {StyleSheet,
  View,
  WebView,
  ScrollView,
  PixelRatio,
  Dimensions
} from 'react-native';


以上即可完成向下滑动屏幕,类似于翻了一页的效果,顺便说一句,官方文档没有写onScrollEndDrag方法,不知是维护人员疏忽还是,该方法存在bug,不管怎么说,先拿来用就是了,出现问题,再想解决方法就是,诶,好艰难的爬过一个坑

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值