美文网首页React Nativereact-native开发React Native开发经验集
react native scrollview深入详解触摸滚动事

react native scrollview深入详解触摸滚动事

作者: liu_520 | 来源:发表于2016-12-15 21:35 被阅读6981次

大家都知道scrollview的几个属性和方法:详细的方法请参考:

江清清专栏:React Native控件之ScrollView组件讲解(14)

这里我就讲解下scrollview的触摸和滑动顺序,并讲解下scrollview的几个触摸方法

1、几个已知的滑动或者滑动开始结束的方法:

onScroll:在滚动过程中, 每帧最多调用一次此函数, 调用的频率可以用scrollEventThrottle属性来控制.

onMomentumScrollEnd:当一帧滚动完毕时调用.

onScrollAnimationEnd :ios上的当滚动动画结束时调用.

2、还有其他的一些事件如下,触摸事件里面有携带event,大家可以再下面的方法里面更改一些view操作就可以打印出来这些event携带的信息了

1、onScrollBeginDrag:一个子view滑动开始拖动开始时触发,注意和onMomentumScrollBegin的区别

2、onScrollEndDrag:一个子view滚动结束拖拽时触发,注意和onMomentumScrollEnd的区别

3、onTouchStart:按下屏幕时触发

4、onTouchMove:移动手指时触发

5、onTouchEnd:手指离开屏幕触摸结束时触发

6、onMomentumScrollBegin:当一帧滚动开始时调用.

7、onMomentumScrollEnd:当一帧滚动完毕时调用.

8、onStartShouldSetResponder:触摸开始时是否成为响应者

9、onStartShouldSetResponderCapture:防止子视图在触摸开始时成为应答器

10、onScrollShouldSetResponder:滚动时是否成为响应者

11、onResponderGrant:开始响应时触发

12、onResponderRelease:手指释放后,视图成为响应者

13、onResponderReject:另一个响应已经被激活, 响应者不会释放它到该视图

14、onScroll:滚动时触发,会触发多次

3、下面就这些方法的顺序做个简单的介绍:

首先在ios上进行测试,测试的结果如下:

scrollview-ios

由上图可以看出执行的顺序,

首先是按下屏幕时触发onTouchStart,

然后手指移动触发onTouchMove,会调用一次或者多次,

如果左右滑动,滑动开始拖动触发onScrollBeginDrag,View开始变化,View成为响应者,

然后onScroll … onTouchMove这两个会触摸多次,

然后手指离开屏幕触发onResponderRelease,

接着触摸结束onTouchEnd

然后是滑动结束拖拽时触发onScrollEndDrag,接着就是一帧滚动的开始onMomentumScrollBegin,它的起始位置和onScrollEndDrag的结束位置重合;

然后是滚动滚动onScroll,

然后是一帧滚动的结束onMomentumScrollEnd,

最后偶尔还会滚动下onScroll,这个有时间不出来,我觉得跟有抖动一样

大家可以自己测试下哦

4、android上的时间分为两种,一个是滑动一次,一个是连续滑动两次甚至多次,详见下图:

4.1、滑动一次

scrollview-android滑动一次的结果

大家可以看出和ios的区别,页面意识滚动了一页

少了个触摸结束onTouchEnd,onResponderGrant、onResponderRelease,这三个(为啥?目前我还不清楚),

直接就是触摸开始-->移动-->开始拖拽-->滚动-->拖拽结束(手指离开了)-->一帧滚动开始-->滚动-->一帧滚动结束-->滚动,

如果不滑动,只是点击离开,只会触发onTouchStart和onTouchEnd;

4.2、滑动两次或者多次:

scrollview-android滑动2次的结果

大家可以看出区别,滑动了两次,

在拖拽开始onScrollBeginDrag和拖拽结束onScrollEndDrag之间没有了滚动onScroll;

然后一帧滚动的开始onMomentumScrollBegin;

然后竟然出发了开始收拾操作的方法onResponderGrant;

再次触发触摸开始:onTouchStart;

然后再一次的拖拽开始onScrollBeginDrag和拖拽结束onScrollEndDrag,中间有了onscroll,可能是滚动变慢了,手指离开了,就有了onScroll;

最后是一帧滚动的结束onMomentumScrollEnd,

这里没有onScroll。

这里的view是滚动了两页也就是从1-2,然后从2-3,最后停在了第三页,也就是一帧开始和结束之间可能存在2-3次的滑动,也就是可能会出现view切换了2-3页面,根据你的滑动的速度和手机的处理能力了。

5、至于FB为何如何设计,我就不得而知了,还希望知道的同学能够分享下。

代码如下:

感兴趣的同学可以自行写一遍代码哦:

scrollview-1 scrollview-2 scrollview-3 scrollview-4

相关文章

网友评论

  • 云深不知处a:楼主,我有一列表,头部固定,左边固定,上下左右联动的,这种怎么做,一个项目就差这个效果了
    云深不知处a:@liu_520 能给我一个demo吗,我写了好多种,效果都不好,一个完整的项目就差者一个了
    云深不知处a:@liu_520 用onScroll这个方法效果不好,一定要加手势吗
    liu_520:@a等风 手势检测吧,左右滑动和上下滑动不都有滑动距离的判断么,
  • Camellieeee:楼主大神,我有个scrollview嵌套ScrollView的问题,当外层ScrollView滑到某个高度后,滑动的响应者变为内部的ScrollView,能通过什么办法做到吗
    liu_520:@Camellieeee 你需要看下手势的定义哦,这个不是三言两语就能讲清的,http://www.tuicool.com/articles/fqIRJjn,你看下这个文章,好好研究下
    Camellieeee:能具体给点思路吗?:joy:
    liu_520:@Camellieeee 重新手势事件吧
  • 羽纱:你好,楼主,据我测试onTouchMove并不会被触发多次,在onScroll时onTouchMove是不会被触发的。有没有什么办法让scrollView滚动时也触发onTouchMove?或者是能得到Touch的位置
    羽纱:@lyxia_ios 打印的结果是:
    touch start
    touch move
    scroll begin
    on scroll
    ...
    不会再有touch move了
    scroll end
    羽纱:class MyScrollView extends React.Component {

    onScroll = (e) => {
    console.log('on scroll')
    }

    render() {
    return (
    <ScrollView

    ref={'scroll'}

    onScroll={this.onScroll}

    onTouchStart={() => console.log('touch start')}

    onTouchMove={() => console.log('touch move')}

    onTouchEnd={() => console.log('touch end')}

    onScrollBeginDrag={() => console.log('scroll begin')}

    onScrollEndDrag={() => console.log('scroll end')}

    onMomentumScrollBegin={() => console.log('momentum begin')}

    onMomentumScrollEnd={() => console.log('momentum end')}

    onStartShouldSetResponder={() => console.log('on start')}

    onStartShouldSetResponderCapture={() => console.log('on start capture')}

    onScrollShouldSetResponder={() => console.log('on scroll')}

    onResponderGrant={() => console.log('granted')}

    onResponderTerminationRequest={() => console.log('term req')}

    onResponderTerminate={() => console.log('term')}

    onResponderRelease={() => console.log('release')}

    onResponderReject={() => console.log('reject')}

    onScrollAnimationEnd={() => console.log('anim end')}

    scrollEventThrottle={16}

    contentContainerStyle={{flexDirection:'column'}}
    >
    {
    this._renderItems()
    }
    </ScrollView>
    )
    }

    _renderItems = ()=>{
    let arr = []
    for(let i=0; i<20; i++) {
    arr.push(<View style={{height:80}} key={i}><Text>{i}</Text></View>)
    }
    return arr
    }
    }

    我这样写并没有在onScroll时onTouchMove是不会被触发的,请楼主帮我看看:sob:
    liu_520:@lyxia_ios 有的,你在ontouchmove方法里更新下state,每次都会触发这个方法的
  • Dadada胖子:请问 onMomentumScrollEnd 这个方法在官方文档怎么没查到呢,是我查到了假文档么:flushed:
    liu_520:@Dadada胖子 客气,有些属性或者方法在官网是查不到的,FB 并没有开放出来,所以查不到
    Dadada胖子:@liu_520 👌,谢谢,我说怎么查不到呢
    liu_520:@Dadada胖子 是的,官网上是没有这个方法的,但是源码里面有这个属性的,这个是ios 里面的native属性
  • f8e5107ee6c8:可以转载嘛楼主,我会讲版权信息来源全部放上可以吗:flushed:
    liu_520:@TrustTheBoy 客气了:smile:
    f8e5107ee6c8:@liu_520 好的,谢谢:pray:
    liu_520:@TrustTheBoy 可以的
  • 挂着铃铛的兔:感谢作者。
    liu_520:@挂着铃铛的兔 这么客气干嘛:smile:

本文标题:react native scrollview深入详解触摸滚动事

本文链接:https://www.haomeiwen.com/subject/dpmgmttx.html