天天看點

【REACT NATIVE 系列教程之一】觸摸事件的兩種形式與四種TOUCHABLE元件詳解

本文是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) =&gt; </code><code>true</code><code>,</code>

<code>      </code><code>onStartShouldSetPanResponderCapture: (evt, gestureState) =&gt; </code><code>true</code><code>,</code>

<code>      </code><code>onMoveShouldSetPanResponder: (evt, gestureState) =&gt; </code><code>true</code><code>,</code>

<code>      </code><code>onMoveShouldSetPanResponderCapture: (evt, gestureState) =&gt; </code><code>true</code><code>,</code>

<code>      </code><code>onPanResponderTerminationRequest: (evt, gestureState) =&gt; </code><code>true</code><code>,  </code>

<code> </code> 

<code>      </code><code>//響應對應事件後的處理:</code>

<code>      </code><code>onPanResponderGrant: (evt, gestureState) =&gt; {</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) =&gt; {</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) =&gt; {</code>

<code>        </code><code>this</code><code>.setState( {eventName:</code><code>'擡手'</code><code>} );</code>

<code>      </code><code>onPanResponderTerminate: (evt, gestureState) =&gt; {</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>&lt;View style={styles.himiViewStyle}</code>

<code>        </code><code>{...</code><code>this</code><code>.myPanResponder.panHandlers}</code>

<code>    </code><code>&gt;</code>

<code>        </code><code>&lt;Text style={styles.himiTextStyle}&gt;Himi React Native 教程&lt;/Text&gt;</code>

<code>        </code><code>&lt;View style={styles.container}&gt;</code>

<code>          </code><code>&lt;Text style={styles.text}&gt;{</code><code>this</code><code>.state.eventName}&lt;/Text&gt;</code>

<code>          </code><code>&lt;Text style={styles.text}&gt;{</code><code>this</code><code>.state.pos}&lt;/Text&gt;</code>

<code>        </code><code>&lt;/View&gt; </code>

<code>    </code><code>&lt;/View&gt;</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>&lt;View style={styles.container}&gt;</code>

<code>        </code><code>&lt;TouchableHighlight </code>

<code>          </code><code>underlayColor=</code><code>'#4169e1'</code>

<code>          </code><code>onPress={</code><code>this</code><code>.test}  </code>

<code>          </code><code>&gt; </code>

<code>            </code><code>&lt;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>/&gt;</code>

<code>        </code><code>&lt;/TouchableHighlight&gt;</code>

<code>        </code><code>&lt;TouchableOpacity </code>

<code>          </code><code>activeOpacity={0.5}    </code>

<code>          </code><code>onPress={()=&gt;{Alert.alert(</code><code>'Himi'</code><code>, </code><code>' TouchableOpacity '</code><code>);} }  </code>

<code>        </code><code>&lt;/TouchableOpacity&gt;</code>

<code>        </code><code>&lt;TouchableWithoutFeedback </code>

<code>          </code><code>onPress={()=&gt;{Alert.alert(</code><code>'Himi'</code><code>, </code><code>' TouchableWithoutFeedback '</code><code>);} }   </code>

<code>        </code><code>&lt;/TouchableWithoutFeedback&gt; </code>

<code>      </code><code>&lt;/View&gt;</code>

由于Himi寫部落格時在Mac下,那麼如下我們來建立除僅限Android的TouchableNativeFeedback之外的三種形式。

根據回報的形式,大家可以自行設定其透明度、背景色、樣式等。

效果圖如下:(點選檢視動态圖)

<a href="http://www.himigame.com/wp-content/uploads/2016/05/user4.gif" target="_blank"></a>

注意:Touchable 元件系列都隻能包含一個子元件,也就是說你想多個,可以嵌套View元件來實作。如:

<code>&lt;TouchableHighlight &gt;  </code>

<code>      </code><code>&lt;View&gt;</code>

<code>            </code><code>&lt;Text&gt; t1 &lt;/Text&gt;  </code>

<code>     </code><code>&lt;Text&gt; t2 &lt;/Text&gt;  </code>

<code> </code><code>&lt;/TouchableHighlight&gt;</code>

<code></code>

本文轉自 xiaominghimi 51CTO部落格,原文連結:http://blog.51cto.com/xiaominghimi/1772385,如需轉載請自行聯系原作者

繼續閱讀