本文是RN(React Native)系列教程第一篇,當然也要給自己的群做個廣告:
React Native @Himi :126100395 剛建立的群,歡迎一起學習、讨論、進步。
本文主要講解兩點:
1. PanResponder:觸摸事件,用以擷取使用者手指所在螢幕的坐标(x,y)或觸發、或滑動、或擡起幾種事件通知。
2. Touchable:React為我們封裝好的觸摸元件。引用原文:“響應系統用起來可能比較複雜。是以我們提供了一個抽象的<code>Touchable</code>實作,用來做“可觸控”的元件。這一實作利用了響應系統,使得你可以簡單地以聲明的方式來配置觸控處理。”
一:觸摸事件各事件響應與坐标擷取
1. 在import React 中添加要使用的觸摸元件:
1
2
3
4
5
<code>import React, {</code>
<code> </code><code>...</code>
<code> </code><code>PanResponder,</code><code>//觸摸必要的元件</code>
<code>} from </code><code>'react-native'</code><code>;</code>
2. 聲明:
6
7
8
<code>constructor(props) {</code>
<code> </code><code>super</code><code>(props);</code>
<code> </code><code>this</code><code>.state = {</code>
<code> </code><code>eventName:</code><code>''</code><code>,</code>
<code> </code><code>pos: </code><code>''</code><code>,</code>
<code> </code><code>};</code>
<code> </code><code>this</code><code>.myPanResponder={}</code>
<code>}</code>
這裡先聲明了兩個變量posX,posY用于顯示坐标用,另外聲明了一個 myPanResponder 用于後面的觸摸事件。
3. 建立、設定與響應
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<code>componentWillMount() {</code>
<code> </code><code>this</code><code>.myPanResponder = PanResponder.create({</code>
<code> </code><code>//要求成為響應者:</code>
<code> </code><code>onStartShouldSetPanResponder: (evt, gestureState) => </code><code>true</code><code>,</code>
<code> </code><code>onStartShouldSetPanResponderCapture: (evt, gestureState) => </code><code>true</code><code>,</code>
<code> </code><code>onMoveShouldSetPanResponder: (evt, gestureState) => </code><code>true</code><code>,</code>
<code> </code><code>onMoveShouldSetPanResponderCapture: (evt, gestureState) => </code><code>true</code><code>,</code>
<code> </code><code>onPanResponderTerminationRequest: (evt, gestureState) => </code><code>true</code><code>, </code>
<code> </code>
<code> </code><code>//響應對應事件後的處理:</code>
<code> </code><code>onPanResponderGrant: (evt, gestureState) => {</code>
<code> </code><code>this</code><code>.state.eventName=</code><code>'觸摸開始'</code><code>;</code>
<code> </code><code>this</code><code>.forceUpdate();</code>
<code> </code><code>},</code>
<code> </code><code>onPanResponderMove: (evt, gestureState) => {</code>
<code> </code><code>var</code> <code>_pos = </code><code>'x:'</code> <code>+ gestureState.moveX + </code><code>',y:'</code> <code>+ gestureState.moveY;</code>
<code> </code><code>this</code><code>.setState( {eventName:</code><code>'移動'</code><code>,pos : _pos} );</code>
<code> </code><code>onPanResponderRelease: (evt, gestureState) => {</code>
<code> </code><code>this</code><code>.setState( {eventName:</code><code>'擡手'</code><code>} );</code>
<code> </code><code>onPanResponderTerminate: (evt, gestureState) => {</code>
<code> </code><code>this</code><code>.setState( {eventName:</code><code>'另一個元件已經成為了新的響應者'</code><code>} )</code>
<code> </code><code>});</code>
<code> </code><code>}</code>
以上代碼分為3部分,先建立,然後對需要追蹤的事件進行設定響應,最後重寫響應的事件進行處理即可。
需要注意的:綁定到componentDidMount的話可能會失效,需要在componentWillMount處預先建立手勢響應器
4. 為要響應的View進行設定
{...this.myPanResponder.panHandlers}
5. 完善Render函數:
<code>render() {</code>
<code> </code><code>return</code> <code>(</code>
<code> </code><code><View style={styles.himiViewStyle}</code>
<code> </code><code>{...</code><code>this</code><code>.myPanResponder.panHandlers}</code>
<code> </code><code>></code>
<code> </code><code><Text style={styles.himiTextStyle}>Himi React Native 教程</Text></code>
<code> </code><code><View style={styles.container}></code>
<code> </code><code><Text style={styles.text}>{</code><code>this</code><code>.state.eventName}</Text></code>
<code> </code><code><Text style={styles.text}>{</code><code>this</code><code>.state.pos}</Text></code>
<code> </code><code></View> </code>
<code> </code><code></View></code>
<code> </code><code>)}</code>
6.用到的布局和樣式:
<code>var</code> <code>styles = StyleSheet.create({</code>
<code> </code><code>container: {</code>
<code> </code><code>flex: 1,</code>
<code> </code><code>flexDirection: </code><code>'row'</code><code>,</code>
<code> </code><code>justifyContent: </code><code>'center'</code><code>,</code>
<code> </code><code>alignItems: </code><code>'center'</code><code>,</code>
<code> </code><code>backgroundColor: </code><code>'#F5FCFF'</code><code>,</code>
<code> </code><code>},</code>
<code> </code><code>text: {</code>
<code> </code><code>color:</code><code>'#f00'</code><code>,</code>
<code> </code><code>fontSize:30,</code>
<code> </code><code>himiViewStyle:{</code>
<code> </code><code>flexDirection: </code><code>'column'</code><code>,</code>
<code> </code><code>himiTextStyle:{</code>
<code> </code><code>marginTop:70,</code>
<code>});</code>
效果如下:(點選檢視動态效果)
<a href="http://www.himigame.com/wp-content/uploads/2016/05/user.gif" target="_blank"></a>
如上是第一種形式,下面我們簡單說下如何使用第二種形式:
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<code> </code>
<code> </code><code>//*********************第二種觸摸的形式*************************** </code>
<code> </code><code>//類似 shouldComponentUpdate,監聽手勢開始按下的事件,傳回一個boolean決定是否啟用目前手勢響應器</code>
<code> </code><code>onStartShouldSetPanResponder: </code><code>this</code><code>._handleStartShouldSetPanResponder.bind(</code><code>this</code><code>),</code>
<code> </code><code>//監聽手勢移動的事件,傳回一個boolean決定是否啟用目前手勢響應器</code>
<code> </code><code>onMoveShouldSetPanResponder: </code><code>this</code><code>._handleMoveShouldSetPanResponder.bind(</code><code>this</code><code>),</code>
<code> </code><code>//手勢開始處理</code>
<code> </code><code>onPanResponderGrant: </code><code>this</code><code>._handlePanResponderGrant.bind(</code><code>this</code><code>),</code>
<code> </code><code>//手勢移動時的處理</code>
<code> </code><code>onPanResponderMove: </code><code>this</code><code>._handlePanResponderMove.bind(</code><code>this</code><code>),</code>
<code> </code><code>//使用者放開所有觸點時的處理</code>
<code> </code><code>onPanResponderRelease: </code><code>this</code><code>._handlePanResponderRelease.bind(</code><code>this</code><code>),</code>
<code> </code><code>//另一個元件成了手勢響應器時(目前元件手勢結束)的處理</code>
<code> </code><code>onPanResponderTerminate: </code><code>this</code><code>._handlePanResponderEnd.bind(</code><code>this</code><code>)</code>
<code> </code>
<code> </code><code>_handleStartShouldSetPanResponder(e, gestureState) {</code>
<code> </code><code>//傳回一個boolean決定是否啟用目前手勢響應器</code>
<code> </code><code>return</code> <code>true</code><code>;</code>
<code> </code><code>} </code>
<code> </code><code>_handleMoveShouldSetPanResponder(e, gestureState) {</code>
<code> </code><code>_handlePanResponderGrant(e, gestureState) {</code>
<code> </code><code>this</code><code>.setState({</code>
<code> </code><code>eventName : </code><code>'Start'</code>
<code> </code><code>}) </code>
<code> </code><code>_handlePanResponderRelease(e, gestureState) {</code>
<code> </code><code>eventName : </code><code>'End'</code>
<code> </code><code>})</code>
<code> </code><code>_handlePanResponderMove(e, gestureState) {</code>
<code> </code><code>var</code> <code>_pos = </code><code>'x:'</code> <code>+ gestureState.moveX + </code><code>',y:'</code> <code>+ gestureState.moveY;</code>
<code> </code><code>eventName : </code><code>'Move:'</code><code>,</code>
<code> </code><code>pos : _pos</code>
<code> </code><code>_handlePanResponderEnd(e, gestureState) {</code>
<code> </code><code>eventName : </code><code>'另一個元件成了手勢響應器時(目前元件觸摸結束)的處理'</code>
第二種形式就是将觸摸響應綁定到我們自定義的函數,其他沒有基本沒差別。改動隻有兩點:
1. 綁定時修改成将觸摸事件的回調綁定到我們自定義函數。
2. 添加每個響應的自定義函數。
<a href="http://www.himigame.com/wp-content/uploads/2016/05/user2.gif" target="_blank"></a>
二:四種 Touchable 觸摸元件
Touchable 一共有四種形式:
TouchableHighlight: 當按下的時候,封裝的視圖的不透明度會降低,同時會有一個底層的顔色透過而被使用者看到,使得視圖變暗或變亮。
TouchableNativeFeedback:(僅限Android平台) 在Android裝置上,這個元件利用原生狀态來渲染觸摸的回報。
TouchableOpacity: 當按下的時候,封裝的視圖的不透明度會降低。這個過程并不會真正改變視圖層級,大部分情況下很容易添加到應用中而不會帶來一些奇怪的副作用。
TouchableWithoutFeedback: 除非你有一個很好的理由,否則不要用這個元件。所有能夠響應觸屏操作的元素在觸屏後都應該有一個視覺上的回報(然而本元件沒有任何視覺回報),仍會觸發觸摸事件的響應
1. 添加Touchable的四種元件
<code> </code><code>Image,</code>
<code> </code><code>Alert,</code>
<code> </code><code>TouchableHighlight,</code>
<code> </code><code>TouchableNativeFeedback,</code>
<code> </code><code>TouchableOpacity,</code>
<code> </code><code>TouchableWithoutFeedback,</code>
<code> </code><code>...</code>
Himi這裡還添加了Image和Alert兩個元件:
Image 是圖檔元件,這裡是為了測試效果,将Touchable發生在圖檔
Alert 彈窗提示元件,是為了通過彈窗,更好的展示出事件響應效果
2. 在Render添加如下:
<code><View style={styles.container}></code>
<code> </code><code><TouchableHighlight </code>
<code> </code><code>underlayColor=</code><code>'#4169e1'</code>
<code> </code><code>onPress={</code><code>this</code><code>.test} </code>
<code> </code><code>> </code>
<code> </code><code><Image </code>
<code> </code><code>source={require(</code><code>'./res/himi.png'</code><code>)} </code>
<code> </code><code>style={{width: 70, height: 70}} </code>
<code> </code><code>/></code>
<code> </code><code></TouchableHighlight></code>
<code> </code><code><TouchableOpacity </code>
<code> </code><code>activeOpacity={0.5} </code>
<code> </code><code>onPress={()=>{Alert.alert(</code><code>'Himi'</code><code>, </code><code>' TouchableOpacity '</code><code>);} } </code>
<code> </code><code></TouchableOpacity></code>
<code> </code><code><TouchableWithoutFeedback </code>
<code> </code><code>onPress={()=>{Alert.alert(</code><code>'Himi'</code><code>, </code><code>' TouchableWithoutFeedback '</code><code>);} } </code>
<code> </code><code></TouchableWithoutFeedback> </code>
<code> </code><code></View></code>
由于Himi寫部落格時在Mac下,那麼如下我們來建立除僅限Android的TouchableNativeFeedback之外的三種形式。
根據回報的形式,大家可以自行設定其透明度、背景色、樣式等。
效果圖如下:(點選檢視動态圖)
<a href="http://www.himigame.com/wp-content/uploads/2016/05/user4.gif" target="_blank"></a>
注意:Touchable 元件系列都隻能包含一個子元件,也就是說你想多個,可以嵌套View元件來實作。如:
<code><TouchableHighlight > </code>
<code> </code><code><View></code>
<code> </code><code><Text> t1 </Text> </code>
<code> </code><code><Text> t2 </Text> </code>
<code> </code><code></TouchableHighlight></code>
<code></code>
本文轉自 xiaominghimi 51CTO部落格,原文連結:http://blog.51cto.com/xiaominghimi/1772385,如需轉載請自行聯系原作者