【React Native 系列教程之一】觸摸事件的兩種形式與四種Touchable組件詳解

ytbf0203 8年前發布 | 44K 次閱讀 ReactNative 移動開發 React Native

本文是RN(React Native)系列教程第一篇,當然也要給自己的群做個廣告:

React Native @Himi :126100395  剛創建的群,歡迎一起學習、討論、進步。

本文主要講解兩點:

1.   PanResponder:觸摸事件,用以獲取用戶手指所在屏幕的坐標(x,y)或觸發、或滑動、或抬起幾種事件通知。

2.   Touchable:React為我們封裝好的觸摸組件。引用原文:“響應系統用起來可能比較復雜。所以我們提供了一個抽象的 Touchable 實現,用來做“可觸控”的組件。這一實現利用了響應系統,使得你可以簡單地以聲明的方式來配置觸控處理。”

一:觸摸事件各事件響應與坐標獲取

1. 在import React 中添加要使用的觸摸組件:

importReact, {
  ...
  PanResponder,//觸摸必要的組件
  ...
} from 'react-native';

2. 聲明:

constructor(props) {
 super(props);
 this.state = {
              eventName:'',
      pos: '',
 };
    this.myPanResponder={}
}

這里先聲明了兩個變量posX,posY用于顯示坐標用,另外聲明了一個 myPanResponder 用于后面的觸摸事件。

3. 創建、設置與響應

componentWillMount() {
      this.myPanResponder = PanResponder.create({
      //要求成為響應者:
      onStartShouldSetPanResponder: (evt, gestureState) => true,
      onStartShouldSetPanResponderCapture: (evt, gestureState) => true,
      onMoveShouldSetPanResponder: (evt, gestureState) => true,
      onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
      onPanResponderTerminationRequest: (evt, gestureState) => true,  
 
      //響應對應事件后的處理:
      onPanResponderGrant: (evt, gestureState) => {
        this.state.eventName='觸摸開始';
        this.forceUpdate();
      },
      onPanResponderMove: (evt, gestureState) => {
        var _pos = 'x:' + gestureState.moveX + ',y:' + gestureState.moveY;
        this.setState( {eventName:'移動',pos : _pos} );
      },
      onPanResponderRelease: (evt, gestureState) => {
        this.setState( {eventName:'抬手'} );
      },
      onPanResponderTerminate: (evt, gestureState) => {
        this.setState( {eventName:'另一個組件已經成為了新的響應者'} )
      },
    });
  }

以上代碼分為3部分,先創建,然后對需要追蹤的事件進行設置響應,最后重寫響應的事件進行處理即可。

需要注意的:綁定到componentDidMount的話可能會失效,需要在componentWillMount處預先創建手勢響應器

4. 為要響應的View進行設置

{...this.myPanResponder.panHandlers}

5. 完善Render函數:

render() {
    return (
    <Viewstyle={styles.himiViewStyle}
        {...this.myPanResponder.panHandlers}
    >
        <Text style={styles.himiTextStyle}>HimiReactNative 教程</Text>
        <Viewstyle={styles.container}>
          <Text style={styles.text}>{this.state.eventName}</Text>
          <Text style={styles.text}>{this.state.pos}</Text>
        </View> 
    </View>

  )}

6.用到的布局和樣式:

var styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  text: {
    color:'#f00',
    fontSize:30,
  },
  himiViewStyle:{
    flex: 1,
    flexDirection: 'column',
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  himiTextStyle:{
    color:'#f00',
    fontSize:30,
    marginTop:70,
  },
});

效果如下:(點擊查看動態效果)

如上是第一種形式,下面我們簡單說下如何使用第二種形式:

componentWillMount() {
    
      this.myPanResponder = PanResponder.create({
 
      //*********************第二種觸摸的形式***************************
      //類似 shouldComponentUpdate,監聽手勢開始按下的事件,返回一個boolean決定是否啟用當前手勢響應器
      onStartShouldSetPanResponder: this._handleStartShouldSetPanResponder.bind(this),
 
      //監聽手勢移動的事件,返回一個boolean決定是否啟用當前手勢響應器
      onMoveShouldSetPanResponder: this._handleMoveShouldSetPanResponder.bind(this),
 
      //手勢開始處理
      onPanResponderGrant: this._handlePanResponderGrant.bind(this),
 
      //手勢移動時的處理
      onPanResponderMove: this._handlePanResponderMove.bind(this),
 
      //用戶放開所有觸點時的處理
      onPanResponderRelease: this._handlePanResponderRelease.bind(this),
 
      //另一個組件成了手勢響應器時(當前組件手勢結束)的處理
      onPanResponderTerminate: this._handlePanResponderEnd.bind(this)
      
    });
  }
 
  _handleStartShouldSetPanResponder(e, gestureState) {
    //返回一個boolean決定是否啟用當前手勢響應器
    return true;
  } 
  _handleMoveShouldSetPanResponder(e, gestureState) {
    return true;
  }
  _handlePanResponderGrant(e, gestureState) {
    this.setState({
      eventName : 'Start'
    })  
  }
  _handlePanResponderRelease(e, gestureState) {
    this.setState({
      eventName : 'End'
    })
  }
  _handlePanResponderMove(e, gestureState) {
    var _pos = 'x:' + gestureState.moveX + ',y:' + gestureState.moveY;
    this.setState({
      eventName : 'Move:',
      pos : _pos
    })
  }
  _handlePanResponderEnd(e, gestureState) {
    this.setState({
      eventName : '另一個組件成了手勢響應器時(當前組件觸摸結束)的處理'
    })
  }

第二種形式就是將觸摸響應綁定到我們自定義的函數,其他沒有基本沒區別。改動只有兩點:

1. 綁定時修改成將觸摸事件的回調綁定到我們自定義函數。

2. 添加每個響應的自定義函數。

效果如下:(點擊查看動態效果)

二:四種 Touchable 觸摸組件     

Touchable 一共有四種形式:

TouchableHighlight: 當按下的時候,封裝的視圖的不透明度會降低,同時會有一個底層的顏色透過而被用戶看到,使得視圖變暗或變亮。

TouchableNativeFeedback:(僅限Android平臺) 在Android設備上,這個組件利用原生狀態來渲染觸摸的反饋。

TouchableOpacity: 當按下的時候,封裝的視圖的不透明度會降低。這個過程并不會真正改變視圖層級,大部分情況下很容易添加到應用中而不會帶來一些奇怪的副作用。

TouchableWithoutFeedback: 除非你有一個很好的理由,否則不要用這個組件。所有能夠響應觸屏操作的元素在觸屏后都應該有一個視覺上的反饋(然而本組件沒有任何視覺反饋),仍會觸發觸摸事件的響應

1. 添加Touchable的四種組件

importReact, {
  ...
  Image,
  Alert,
  TouchableHighlight,
  TouchableNativeFeedback,
  TouchableOpacity,
  TouchableWithoutFeedback,
  ...
} from 'react-native';

Himi這里還添加了Image和Alert兩個組件:

Image 是圖片組件,這里是為了測試效果,將Touchable發生在圖片

Alert 彈窗提示組件,是為了通過彈窗,更好的展示出事件響應效果

2. 在Render添加如下:

<Viewstyle={styles.container}>
        <TouchableHighlight
          underlayColor='#4169e1'
          onPress={this.test}  
          > 
            <Image 
            source={require('./res/himi.png')} 
            style={{width: 70, height: 70}} 
            />
        </TouchableHighlight>
 
        <TouchableOpacity
          activeOpacity={0.5}    
          onPress={()=>{Alert.alert('Himi', ' TouchableOpacity ');} }  
          > 
            <Image 
            source={require('./res/himi.png')} 
            style={{width: 70, height: 70}} 
            />
        </TouchableOpacity>
 
        <TouchableWithoutFeedback
          underlayColor='#4169e1'
          activeOpacity={0.5}    
          onPress={()=>{Alert.alert('Himi', ' TouchableWithoutFeedback ');} }  
          > 
            <Image 
            source={require('./res/himi.png')} 
            style={{width: 70, height: 70}} 
            />
        </TouchableWithoutFeedback> 
      </View>

由于Himi寫博客時在Mac下,那么如下我們來創建除僅限Android的TouchableNativeFeedback之外的三種形式。

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

效果圖如下:(點擊查看動態圖)

 

來自: http://www.himigame.com/react-native/2203.html

 

 本文由用戶 ytbf0203 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!