[深入剖析React Native]React Native元件之Touchable*
Touchable*系列元件封裝了觸控點選的相關事件,比如:觸控、點選、長按、反饋等,官方提供Touchable*系列元件包括四種:
- TouchableHighlight
- TouchableNativeFeedback
- TouchableOpacity
- TouchableWithoutFeedback
其中,TouchableWithoutFeedback的觸控點選不帶反饋效果,其他三個都有反饋效果。
TouchableWithoutFeedback
官方建議不使用該元件,因為任何可以響應事件的元件在觸控or點選的時候應該有視覺上的反應效果,但是這個元件沒有。這個元件看起來像Web效果而不是原生(Native)效果。
**注意:**TouchableWithFeedback只支援一個子節點,如果你需要設定多個子檢視元件,那麼就需要使用View節點進行包裝。
屬性方法
- accessibilityComponentType --View.AccessibilityComponentType 設定可訪問的元件型別
- accessibilityTraits -- View.AccessibilityTraits,[View.AccessibilityTraits] 設定訪問特徵
- accessible -- bool 設定當前元件是否可以訪問
- delayLongPress -- number 設定延遲的時間,單位為毫秒。從onPressIn方法開始,到onLongPress被呼叫這一段時間
- delayPressIn -- number 設定延遲的時間,單位為毫秒,從使用者觸控控制元件開始到onPressIn被呼叫這一段時間
- delayPressOut -- number 設定延遲的時間,單位為毫秒,從使用者觸控事件釋放開始到onPressOut被呼叫這一段時間
- onLayout -- function 當元件載入或者改元件的佈局發生變化的時候呼叫。呼叫傳入的引數為{nativeEvent:{layout:{x,y,width,height}}}
- onLongPress -- function 方法,當用戶長時間按壓元件(長按效果)的時候呼叫該方法
- onPress -- function 方法 當用戶點選的時候呼叫(觸控結束)。 但是如果事件被取消了就不會呼叫。(例如:當前被滑動事件所替代)
- onPressIn -- function 使用者開始觸控元件回撥方法
- onPressOut -- function 使用者完成觸控元件之後回撥方法
- pressRetentionOffset {top:number,left:number,bottom:number,right:number} 該設定當檢視滾動禁用的情況下,可以定義當手指距離元件的距離。當大於該距離該元件會失去響應。當少於該距離的時候,該元件會重新進行響應。
該元件我們一般不會直接進行使用,下面三種Touchable*系列元件對於該元件的屬性方法都可以進行使用。具體會具體演示這些屬性方法的使用例項。
TouchableHighlight觸控高亮
該元件進行封裝檢視觸控點選的屬性。當手指點選按下的時候,該檢視的不透明度會進行降低同時會看到相應的顏色(檢視變暗或者變亮)。如果我們去檢視該元件的原始碼會發現,該底層實現是添加了一個新的檢視。如果我們沒有正確的使用,就可能不會出現正確的效果。例如:我們沒有給該元件檢視設定backgroudnColor的顏色值。
TouchableHighlight只支援一個子節點,如果你需要設定多個子檢視元件,那麼就需要使用View節點進行包裝。
屬性方法
- TouchableWithoutFeedback的 屬性,這邊TouchableHighlight元件全部可以進行使用
- activeOpacity -- number 該用來設定檢視在進行觸控的時候,要要顯示的不透明度(通常在0-1之間)
- onHideUnderlay -- function 方法 當底層被隱藏的時候呼叫
- onShowUnderlay -- function 方法 當底層顯示的時候呼叫
- style -- 可以設定控制元件的風格演示,該風格演示可以參考View元件的style
- underlayColor -- 當觸控或者點選控制元件的時候顯示出的顏色
TouchableWithoutFeedback、TouchableHighlight例項
'use strict';
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
TouchableHighlight,
TouchableWithoutFeedback,
} from 'react-native';
export default class TouchableMazouri extends Component {
render() {
return (
<View style={styles.container}>
<TouchableHighlight
underlayColor="rgb(210, 230, 255)"
activeOpacity={0.5}
style={styles.touchable}
onHideUnderlay={() => console.log("onHideUnderlay")}
onShowUnderlay={() => console.log("onShowUnderlay")}
// accessible={false}
onPress={() => console.log("onPress TouchableHighlight")}
onLongPress={() => console.log("onLongPress TouchableHighlight")}
onPressIn={() => console.log("onPressIn TouchableHighlight")}
onPressOut={() => console.log("onPressOut TouchableHighlight")}
pressRetentionOffset={{top:200,left:50,bottom:0,right:50}}
delayPressIn={2000}
delayPressOut={2000}
delayLongPress={2000}
>
<Text style={{fontSize:16}}>我是TouchableHighlight,點我吧</Text>
</TouchableHighlight>
<TouchableWithoutFeedback
style={styles.touchable}
// accessible={false}
onPress={() => console.log("onPress TouchableWithoutFeedback")}
onLongPress={() => console.log("onLongPress TouchableWithoutFeedback")}
onPressIn={() => console.log("onPressIn TouchableWithoutFeedback")}
onPressOut={() => console.log("onPressOut TouchableWithoutFeedback")}
>
<View><Text style={{fontSize:16}}>我是TouchableWithoutFeedback,點我吧</Text></View>
</TouchableWithoutFeedback>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
touchable: {
borderWidth: 1,
borderRadius: 8,
borderColor: '#e0e0e0',
backgroundColor: '#e5eCee',
}
});
TouchableOpacity透明度變化
該元件封裝了響應觸控事件。當點選按下的時候,該元件的透明度會降低。該元件使用過程中並不會改變檢視的層級關係,而且我們可以非常容易的新增到應用並且不會產生額外的異常錯誤。
屬性方法
- TouchableWithoutFeedback的屬性,這邊TouchableOpacity元件全部可以進行使用
- activeOpacity -- number 設定當用戶觸控的時候,元件的透明度
TouchableNativeFeedback(Android專用)
該封裝了可以進行響應觸控事件的元件(僅限Android平臺)。在Android平臺上面該該元件可以使用原生平臺的狀態資源來顯示觸控狀態變化。【特別注意】現如今該元件只是支援僅有一個View的子檢視例項(作為子節點)。在底層實現上面實際上面是建立一個新的RCTView的節點來進行替換當前的View節點檢視,並且可以攜帶一些附加的屬性。
該元件觸控反饋的背景圖資源可以通過background屬性進行自定義設定
下面一個很簡單的使用例項方法如下:
'use strict';
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
TouchableHighlight,
TouchableWithoutFeedback,
TouchableOpacity,
TouchableNativeFeedback,
} from 'react-native';
export default class TouchableMazouri extends Component {
render() {
return (
<View style={styles.container}>
<TouchableHighlight
underlayColor="rgb(210, 230, 255)"
activeOpacity={0.5}
style={styles.touchable}
onHideUnderlay={() => console.log("onHideUnderlay")}
onShowUnderlay={() => console.log("onShowUnderlay")}
// accessible={false}
onPress={() => console.log("onPress TouchableHighlight")}
onLongPress={() => console.log("onLongPress TouchableHighlight")}
onPressIn={() => console.log("onPressIn TouchableHighlight")}
onPressOut={() => console.log("onPressOut TouchableHighlight")}
pressRetentionOffset={{top:200,left:50,bottom:0,right:50}}
delayPressIn={2000}
delayPressOut={2000}
delayLongPress={2000}
>
<Text style={{fontSize:16}}>我是TouchableHighlight,點我吧</Text>
</TouchableHighlight>
<TouchableWithoutFeedback
style={styles.touchable}
// accessible={false}
onPress={() => console.log("onPress TouchableWithoutFeedback")}
onLongPress={() => console.log("onLongPress TouchableWithoutFeedback")}
onPressIn={() => console.log("onPressIn TouchableWithoutFeedback")}
onPressOut={() => console.log("onPressOut TouchableWithoutFeedback")}
>
<View><Text style={{fontSize:16}}>我是TouchableWithoutFeedback,點我吧</Text></View>
</TouchableWithoutFeedback>
<TouchableOpacity
activeOpacity={0}
style={styles.touchable}
onPress={() => console.log("onPress TouchableOpacity")}
onLongPress={() => console.log("onLongPress TouchableOpacity")}
onPressIn={() => console.log("onPressIn TouchableOpacity")}
onPressOut={() => console.log("onPressOut TouchableOpacity")}
>
<Text style={{fontSize:16}}>我是TouchableOpacity,點我就隱藏</Text>
</TouchableOpacity>
<TouchableNativeFeedback
style={styles.touchable}
>
<View style={{backgroundColor: 'blue'}}>
<Text style={{fontSize:16}}>我是TouchableNativeFeedback,點我吧</Text>
</View>
</TouchableNativeFeedback>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
touchable: {
borderWidth: 1,
borderRadius: 8,
borderColor: '#e0e0e0',
backgroundColor: '#e5eCee',
marginTop: 20,
}
});
屬性方法
- TouchableWithoutFeedback的 屬性,這邊TouchableNativeFeedback元件全部可以進行使用
- background -- backgroundPropType 該用來設定背景資源的型別,該屬性會傳入一個type屬性和依賴的額外資源的data的物件。官方推薦採用如下的靜態方法來進行生成該dictionary物件
生成該dictionary物件
- TouchableNativeFeedback.SelectableBackground() -- 該會建立使用android預設主題背景(?android:attr/selectableItemBackground)
- TouchableNativeFeedback.SelectableBackgroundBorderless() -- 該會建立使用android預設的無框的主題背景(?android:attr/selectableItemBackgroundBorderless)。不過該引數需要Android API 21+才可以使用
- TouchableNativeFeedback.Ripple(color,borderless) -- 該會建立當元件被按下的時候有一個水滴的效果.通過color引數指定顏色,如果borderless為true的時候,那麼該水滴效果會渲染到該元件檢視的外邊。同樣該背景型別引數也需要Android API 21+才可以使用
'use strict';
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
TouchableHighlight,
TouchableWithoutFeedback,
TouchableOpacity,
TouchableNativeFeedback,
} from 'react-native';
export default class TouchableMazouri extends Component {
render() {
return (
<View style={styles.container}>
<TouchableHighlight
underlayColor="rgb(210, 230, 255)"
activeOpacity={0.5}
style={styles.touchable}
onHideUnderlay={() => console.log("onHideUnderlay")}
onShowUnderlay={() => console.log("onShowUnderlay")}
// accessible={false}
onPress={() => console.log("onPress TouchableHighlight")}
onLongPress={() => console.log("onLongPress TouchableHighlight")}
onPressIn={() => console.log("onPressIn TouchableHighlight")}
onPressOut={() => console.log("onPressOut TouchableHighlight")}
pressRetentionOffset={{top:200,left:50,bottom:0,right:50}}
delayPressIn={2000}
delayPressOut={2000}
delayLongPress={2000}
>
<Text style={{fontSize:16}}>我是TouchableHighlight,點我吧</Text>
</TouchableHighlight>
<TouchableWithoutFeedback
style={styles.touchable}
// accessible={false}
onPress={() => console.log("onPress TouchableWithoutFeedback")}
onLongPress={() => console.log("onLongPress TouchableWithoutFeedback")}
onPressIn={() => console.log("onPressIn TouchableWithoutFeedback")}
onPressOut={() => console.log("onPressOut TouchableWithoutFeedback")}
>
<View><Text style={{fontSize:16}}>我是TouchableWithoutFeedback,點我吧</Text></View>
</TouchableWithoutFeedback>
<TouchableOpacity
activeOpacity={0}
style={styles.touchable}
onPress={() => console.log("onPress TouchableOpacity")}
onLongPress={() => console.log("onLongPress TouchableOpacity")}
onPressIn={() => console.log("onPressIn TouchableOpacity")}
onPressOut={() => console.log("onPressOut TouchableOpacity")}
>
<Text style={{fontSize:16}}>我是TouchableOpacity,點我就隱藏</Text>
</TouchableOpacity>
<TouchableNativeFeedback
style={styles.touchable}
>
<View style={{backgroundColor: 'blue'}}>
<Text style={{fontSize:16}}>我是TouchableNativeFeedback,點我吧</Text>
</View>
</TouchableNativeFeedback>
<TouchableNativeFeedback
style={styles.touchable}
background={TouchableNativeFeedback.SelectableBackground()}
>
<View>
<Text style={{fontSize:16}}>selectableItemBackground,點我吧</Text>
</View>
</TouchableNativeFeedback>
<TouchableNativeFeedback
style={styles.touchable}
background={TouchableNativeFeedback.SelectableBackgroundBorderless()}
>
<View>
<Text style={{fontSize:16}}>selectableItemBackgroundBorderless,點我吧</Text>
</View>
</TouchableNativeFeedback>
<TouchableNativeFeedback
style={styles.touchable}
background={TouchableNativeFeedback.Ripple('#fff000', false)}
>
<View>
<Text style={{fontSize:16}}>selectableItemBackgroundBorderless false,點我吧</Text>
</View>
</TouchableNativeFeedback>
<TouchableNativeFeedback
style={styles.touchable}
background={TouchableNativeFeedback.Ripple('#000fff', true)}
>
<View>
<Text style={{fontSize:16}}>selectableItemBackgroundBorderless true,點我吧</Text>
</View>
</TouchableNativeFeedback>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
touchable: {
borderWidth: 1,
borderRadius: 8,
borderColor: '#e0e0e0',
backgroundColor: '#e5eCee',
marginTop: 20,
}
});