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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM