React Native:手勢響應系統
在移動設備上的手勢識別要比網頁版復雜的多。 簡單的一個觸碰,就會根據不同應用,用戶的使用意圖,分成好幾個階段。例如:應用需要判斷出來這個觸摸是上下滾動,還是在小工具之間滑動,或是敲擊。有些甚至可以在觸碰的過程中發生變化。還有一些同時發生的觸碰。
觸碰響應系統就需要組件能夠和這些觸碰互動交流,而不需要再為他們的父類或是繼承的子類開發更多的代碼。這個系統是在 ResponderEventPlugin.js里面完成的,這文件本身也有一些更詳細的介紹文檔。
來練習一把
用戶在使用原生應用與 web apps 時,用戶體驗絕然不同, 這也是一個很大的原因,大家都要求開發原生應用。每一個動作都應該具有下列的屬性:
- 回饋/高亮顯示: 告訴用戶誰在處理他們的手勢命令,同時也展示出來一旦停止了手勢,會發生什么。
- 可以取消:當做一個動作時,用戶可以在動作做到一半的時候取消掉,取消的方式就是把手指移開,而無須其它更多操作。
這些屬性會讓用戶在使用應用的時候,感覺更舒服些,因為他可以讓用戶放心大膽的使用應用,而無須擔心犯任何錯誤。
TouchableHighlight 和 Touchable*
響應系統的使用相對來說比較困難。所以我們提供了一個抽象的類來繼承了響應系統: Touchable, 該類就是給那些可以敲擊的組件使用。這個使用的是響應系統,同時也可以讓你很輕松的配置敲擊交互。當你要使用按鈕或是網頁鏈接時,記得調用 TouchableHighlight 類。
響應器的生命周期
一個視圖在繼承了正確的協商方式后,就可以變成一個觸碰響應器。 這里有兩個方法可以請求視圖是否想要成為響應器:
- View.props.onStartShouldSetResponder: (evt) => true, 該語句會詢問視圖,是否在觸碰動作開始后就變成響尖器?
- View.props.onMoveShouldSetResponder: (evt) => true:該語句會在該視圖還不是響應器時,在執行的每一個觸碰動作,都會去詢問視圖:是否現在想變成響應式的觸碰?
-
如果視圖返回來的是 True,表示他想成為響應器,那么接下來兩件事中的某一個將會發生:
- View.props.onResponderGrant: (evt) => {}: 現在視圖就會開始響應觸碰事伯。 也會在這個時間向用戶展示接下來會發生什么。
- View.props.onResponderReject: (evt) => {} :表示現在有其他的組件正在做為響應器執行任務,這會兒還沒有被釋放出來。
如果視圖正在響應,那么下面的句柄會被調用到:
- View.props.onResponderMove: (evt) => {}: 用戶正在移動手指
- View.props.onResponderMove: (evt) => {}: 表示觸碰動作結束時關系,比方說: touchup.
- View.props.onResponderTerminationRequest: (evt) => true: 有其他的組件想要成為響應器。那么當前做為響應器的視圖是否愿意釋放?返回 true就表示愿意釋放。
- View.props.onResponderTerminate: (evt) => {}: 表示響應器的權限已經從視圖身上拿走了。有可能是被其它視圖通過調用:onResponderTerminationRequest 后搶走了,也有可能被操作系統不打招呼,直接拿走。(在 iOS系統里就是發生在控制中心或是通知中心)。
evt 算是一個合成的觸碰事件,他主要有下面的一些形式:
NativeEvent:
- changedTouches: 因為上一個事件引起了所有觸碰事件的數組發生了變化。
- identifier: 觸碰的 ID.
- locationX: 相對于事件來說,觸碰的 X 位置
- locationY: 相對于事件來說,觸碰的Y位置
- pageX: 相對于屏幕來說,觸碰的X位置
- pageY: 相對于屏幕來說,觸碰的 Y位置
- target: 組件的節點ID正在接收觸碰事件
- timestamp: 觸碰的時間標識,對于速度計算特別有用。
- touches: 屏幕上所有當前觸碰的數組
捕獲 ShouldSet 句柄
onStartShouldSetResponder 和 onMoveShouldSetResponder 的調用是使用冒泡模式,在最深處的節點最先被調用。 這也就意味著當多視圖模式在*ShouldSetResponder 句柄返回為 true 時,最深的控件將成為響應器。 這種設計在大多數情況下是可取的,這樣才能保證所有的控制和按鈕是可用的。
但在有些特別情況,某些父類更想變成響應器。 這種情況就可以通過捕獲位相來處理了。 在響應系統利用冒泡模式賦值給最深的組件之前,先捕獲位相,調用:on*ShouldSetResponderCapture . 所以現在如果某個父類視圖想要阻止他的子類在觸碰開始就變成了響應器,他應該擁用 onStartShouldSetResponderCapture 句柄,并返回 true.
- View.props.onStartShouldSetResponderCapture: (evt) => true,
- View.props.onMoveShouldSetResponderCapture: (evt) => true,
PanResponder
對于高階的手勢說明,請參照: PanResponder
不深思則不能造于道。不深思而得者,其得易失。
名人名言- 曾國藩
- By 優聯實達
- 2015-10-30
- 2544
- 公司新聞,網站開發,網站設計,UI