【React Native 系列教程之一】觸摸事件的兩種形式與四種Touchable組件詳解
本文是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