RN ScroolView 從物理學(xué)角度理解觸摸滾動事件

前言

本文旨在介紹React Native ScrollView官方文檔中未提及的滾動事件API,著重介紹如何從物理學(xué)角度理解onMomentumScrollBeginonMomentumScrollEnd函數(shù)。

至于官方文檔中為何不提及這些API,個人理解是目前文檔也在不斷更新,文檔還未完善。亦或是我打開的姿勢不對?希望知道的朋友能科普下,解鎖新的姿勢。

ScrollView簡介

一個包裝了平臺的ScrollView(滾動視圖)的組件,同時還集成了觸摸鎖定的“響應(yīng)者”系統(tǒng)。
記住ScrollView必須有一個確定的高度才能正常工作,因?yàn)樗鼘?shí)際上所做的就是將一系列不確定高度的子組件裝進(jìn)一個確定高度的容器(通過滾動操作)。要給一個ScrollView確定一個高度的話,要么直接給它設(shè)置高度(不建議),要么確定所有的父容器都已經(jīng)綁定了高度。在視圖棧的任意一個位置忘記使用{flex:1}都會導(dǎo)致錯誤,你可以使用元素查看器來查找問題的原因。
ScrollView內(nèi)部的其他響應(yīng)者尚無法阻止ScrollView本身成為響應(yīng)者。

官方文檔介紹的API

官方文檔中提及了三個與事件回調(diào)相關(guān)的API,如下所示:


圖-1

官方文檔未介紹的API

此處只列出ScrollView特有的事件回調(diào)API,關(guān)于“響應(yīng)者系統(tǒng)”的回調(diào)API一下就不列出了。

API Description
onTouchStart 按下屏幕時觸發(fā)
onTouchMove 移動時觸發(fā),實(shí)際上按住不動也會觸發(fā)
onTouchEnd 手指離開屏幕時觸發(fā),Android測試當(dāng)有拖曳行為時會調(diào)用onScrollEndDrag來代替之;當(dāng)無拖曳行為時,手指離開就會觸發(fā)
onScrollBeginDrag 開始拖動時觸發(fā),滾動開始的標(biāo)志
onScroll 滾動過程中調(diào)用,一幀最多調(diào)用一次
onScrollEndDrag 拖曳結(jié)束時調(diào)用,頂替onTouchEnd
onMomentumScrollBegin 手指離開屏幕時調(diào)用(瞬時沖量滑動的開始)
onMomentumScrollEnd 滾動結(jié)束時調(diào)用(瞬時沖量滑動的結(jié)束)

起初很不理解最后倆個方法的描述,網(wǎng)上一查資料,解釋為“一幀滾動的開始結(jié)束”,“幀滾動”是什么鬼?一臉懵逼,我拖曳的時候畫面不是一直在滾動嗎?意思會調(diào)用好幾次?百度、google無果,只能一臉懵逼的自己寫Demo驗(yàn)證了。
Momentum一詞指物理學(xué)中動量,再解釋之前,我們先回顧下高中所學(xué)的物理知識。
動量定理

圖-2

瞬時沖量:極短時間內(nèi)力F產(chǎn)生的沖量,簡單點(diǎn)就理解為物體的速度會突變,舉個例子就是你給一個靜止的物體,施加一個瞬時沖量,那瞬間,物體的速度會從0突變到另外一個值,而位移未曾改變。

結(jié)論:這組函數(shù)是用于響應(yīng)你手指在離開屏幕那一剎那(極短時間),對物體在滑動反方向上所施加力的作用效果,這時會產(chǎn)生一個瞬時沖量,至使物體速度突變,之后的滑動過程就是一個減速運(yùn)動至速度為零(ScrollView內(nèi)部會模擬產(chǎn)生一個摩擦力)。
這就是為什么在ScrollView的實(shí)際操作當(dāng)中,當(dāng)我們用力滑動一小截,ScrollView就會連翻好幾頁的原因。
簡而言之
onMomentumScrollBegin會在你手指離開屏幕時調(diào)用,不過在此之前會先調(diào)用onScrollDragEnd,onMomentumScrollEnd會在滑動結(jié)束時調(diào)用。

Demo測試驗(yàn)證

測試情景一:
手指按住,不移動(持續(xù)1-2s),然后離開屏幕,測試結(jié)果如下如所示:

圖-3

可見onTouchMove在測試期間共調(diào)用了35次,并不是如網(wǎng)上所言在移動時候調(diào)用,而是在onTouchStart后就會調(diào)用,手指離開屏幕就會調(diào)用onTouchEnd結(jié)束事件響應(yīng)。
注意,onTouchMove傳進(jìn)來的nativeEvent并沒有contentOffset屬性(圖片相對ScrollView容器的滑動偏移量)如圖-4所示,這也從另外一個方面說明它不是在移動的時候調(diào)用。
圖-4

測試情景二:
手指按住屏幕,慢慢的拖動一段距離,再最后要離開屏幕時,手指往滑動反方向用力,測試結(jié)果如下所示,圖中數(shù)字表示滑動方向的偏移量:
圖-5

上面說到onTouchMove并不是在滑動時調(diào)用,那么滑動開始回調(diào)API是誰呢?聰明的你肯定想到了,沒錯就是onScrollBeginDrag,代表滑動的開始。該函數(shù)接收的nativeEvent才包含了contentOffset屬性,如圖-5所示。

圖-6

onScroll就是在滑動的過程中會調(diào)用。
重點(diǎn)來了,
在你手指離開屏幕時,會先調(diào)用onScrollEndDrag,表示拖動結(jié)束,接下來,就如上面我們分析的一樣,根據(jù)你手指離開屏幕時所施加的力,計算這個瞬時沖量該讓圖片滑動多少距離。依次調(diào)用onMomentumScrollBegin,onScroll,onMomentumScrollEnd。
測試代碼就不上了,太長了,寫起來也很簡單。

最后,由于本人水平有限,第一次寫文章,文中難免有不妥之處,還請多多體諒。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,221評論 4 61
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,001評論 25 709
  • 2014的 O2O 想要革傳統(tǒng)行業(yè)的命,幾乎所有的行業(yè)都有 O2O 創(chuàng)業(yè)公司的身影,這股熱潮也讓我心生萌芽,但當(dāng)我...
    秋橙閱讀 560評論 0 2
  • 問題描述 笨方法:O(n2) 分治O(nlogn) 1)將數(shù)組分成兩半,分別求出左半邊的逆序數(shù)和右半邊的序數(shù)2)再...
    Co_zy閱讀 959評論 0 1

友情鏈接更多精彩內(nèi)容