• react-native 之ScrollView的使用


    1. 分页效果设置 pagingEnabled={true}

    <ScrollView
                      ref={e => this.scroll = e}
                      horizontal={true}
                      directionalLockEnabled
                      showsHorizontalScrollIndicator={false}
                      pagingEnabled={true}
                      onMomentumScrollEnd={(event)=>{
                        this.onScrollEnd(event,this.scroll)
                      }}
                      scrollEventThrottle={3750}
                      onScroll = {this.handleScroll}
    
                    >
    </ScrollView>

    2. 要知道当前滚动到第几页,可以在 handleScroll 方法中处理。这里我做的时候有一个问题,

    ref={e => this.scroll = e} 我在
    onScrollEnd(event,scroll){
    
        //不要用this.scroll 它为null
        console.log('onScrollEnd'+ scroll)
    
      }

    中得到却是null , 后来参考了:http://www.360doc.com/content/16/0930/14/35331283_594878202.shtml 。决定用

    handleScroll 试试,但是
    handleScroll 一滑动界面就会调用,调用的频率高,却又能用scrollEventThrottle={3750} 控制,这个具体怎么控制,暂时还不知道。
    handleScroll(event){//滑动就会调用
        console.log(event.nativeEvent.contentOffset.x);//水平滚动距离
        //console.log(event.nativeEvent.contentOffset.y);//垂直滚动距离
        if(event.nativeEvent.contentOffset.x%375==0){
          const currentPageIndex = event.nativeEvent.contentOffset.x/375;
          console.log('当前滚动到了'+event.nativeEvent.contentOffset.x/375);
          EventBus.getInstance().fireEvent("NeedChangeTabIndex", {
              currentPageIndex
          })
        }
      }
    在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,不管怎么说,先拿来用就是了,出现问题,再想解决方法就是,诶,好艰难的爬过一个坑
    View Code
    此文仅为鄙人学习笔记之用,朋友你来了,如有不明白或者建议又或者想给我指点一二,请私信我。liuw_flexi@163.com/QQ群:582039935. 我的gitHub: (学习代码都在gitHub) https://github.com/nwgdegitHub/
  • 相关阅读:
    关于线程间通信的条件变量
    vim学习相关链接
    CString与输入输出流对象问题。
    CRect类 的介绍
    在vs中char类型的实参与LPCWSTR类型的形参类型不兼容怎么解决?
    ADO Recordset 对象链接
    FIND_IN_SET的简单使用
    html meta标签作用
    github新建托管项目及上传项目
    Javascript编码规范
  • 原文地址:https://www.cnblogs.com/liuw-flexi/p/12214299.html
Copyright © 2020-2023  润新知