react-native中View组件这是单纯的视图容器,并不能响应交互变化,绑定事件,rn提供了TouchableOpacity等封装组件以正确响应触摸操作。
- TouchableWithoutFeedback:单纯的用户点击触摸响应组件,不会改变视图UI,仅绑定press、longPress等事件;
- TouchableOpacity:响应用户触摸操作,继承TouchableWithoutFeedback组件所有功能与属性,点击下降低视图透明度,可以绑定perss、longPress等事件;
- TouchableHighlight:响应用户触摸操作,继承TouchableWithoutFeedback组件所有功能与属性,点击下背景变暗,可以添加press、longPress等事件绑定;
- TouchableNativeFeedback:Android平台组件,继承TouchableWithoutFeedback组件所有功能与属性,同时可以设置background用于反馈触摸操作(形成波纹背景效果)
1. TouchableWithoutFeedback
TouchableWithoutFeedback组件仅支持一个直系子组件,若有多个组件,请用外层view进行包裹。
style
添加style:
export default class Test extends React.Component{
render(){
return(
//为组件TouchableWithoutFeedback设置样式,并不能产生任何UI效果
<TouchableWithoutFeedback style={styles.touchable}>
<View style={styles.viewBox}>
<Text style={styles.test}>TEST</Text>
</View>
</TouchableWithoutFeedback>
)
}
}
//样式部分,下同
const styles=StyleSheet.create({
container:{
flex:1,
justifyContent:'center',
alignItems:'center'
},
touchable:{
backgroundColor:'#999',
borderColor:'#ca6',
borderWidth:10,
height:300,
width:200,
},
viewBox:{
justifyContent:'center',
alignItems:'center',
},
test:{
color:'#f00',
fontWeight:'600',
fontSize:40,
}
})
效果:
修改style添加位置:
export default class Test extends React.Component{
render(){
return(
<TouchableWithoutFeedback>
//将touchable样式对象添加到View组件中
<View style={[styles.touchable,styles.viewBox]}>
<Text style={styles.test}>TEST</Text>
</View>
</TouchableWithoutFeedback>
)
}
}
效果:
onPress
为组件添加点击事件,由于View不能绑定点击事件,而TouchableFeedback不会改变样式,则需要给视图添加点击事件时,可以用TouchableFeedback替代View组件。
export default class Test extends React.Component{
render(){
return(
<View style={styles.container}>
<TouchableWithoutFeedback
onPress={()=>{alert('onPress事件')}}
>
<View style={[styles.touchable,styles.viewBox]}>
<Text style={styles.test}>TEST</Text>
</View>
</TouchableWithoutFeedback>
</View>
)
}
}
效果:
onLongPress
长时间点击操作响应事件:
export default class Test extends React.Component{
render(){
return(
<View style={styles.container}>
<TouchableWithoutFeedback
onPress={()=>{alert('这是Press')}}
onLongPress={()=>{alert('这是LongPress')}}
>
<View style={[styles.touchable,styles.viewBox]}>
<Text style={styles.test}>TEST</Text>
</View>
</TouchableWithoutFeedback>
</View>
)
}
}
效果:
- onPressIn、onPressOut
pressIn表示触摸开始回调、pressOut表示触摸结束回调
export default class Test extends React.Component{
render(){
return(
<View style={styles.container}>
<TouchableWithoutFeedback
onPressIn={()=>{alert('PressIn事件')}}
onPressOut={()=>{alert('PressOut事件')}}
>
<View style={[styles.touchable,styles.viewBox]}>
<Text style={styles.test}>TEST</Text>
</View>
</TouchableWithoutFeedback>
</View>
)
}
}
效果:
- onLayout
onLayout可以用于获取当前组件高、宽以及位置;
还可以用于检测设备横竖屏模式;
export default class Test extends React.Component{
render(){
return(
<View style={styles.container}>
<TouchableWithoutFeedback
onLayout={(props)=>{console.log(props.nativeEvent)}}
>
<View style={[styles.touchable,styles.viewBox]}>
<Text style={styles.test}>TEST</Text>
</View>
</TouchableWithoutFeedback>
</View>
)
}
}
//浏览器调试结果为:
{
layout:{
height:300,//高度300
width:200,//宽度200,可以通过高度与宽度比较进行确定横竖屏
x:80,//距离父组件左边框距离
y:133.5,//距离父组件上边框高度
},
target:4//当前组件以及所有后代组件的数量,文本也+1
}
hitSlop
定义触摸响应的偏移范围,其值为一偏移对象
object: {top: number, left: number, bottom: number, right: number}
,即触摸于视图范围外的偏移量内都能响应press事件,但是偏移不能超出父组件;
export default class Test extends React.Component{
render(){
return(
<View style={styles.container}>
<TouchableWithoutFeedback
//设置top,bottom,left,right的偏移位置,从效果图可看出press事件的有效范围
hitSlop={{top:100,left:50,right:50,bottom:100}}
onPress={()=>{alert(12121)}}
>
<View style={[styles.touchable,styles.viewBox]}>
<Text style={styles.test}>TEST</Text>
</View>
</TouchableWithoutFeedback>
</View>
)
}
}
效果:
- pressRetentionOffset
在当前视图不能滚动的前提下指定这个属性,可以决定当手指移开多远距离之后,会不再激活按钮。但如果手指再次移回范围内,按钮会被再次激活。只要视图不能滚动,你可以来回多次这样的操作。确保你传入一个常量来减少内存分配。
export default class Test extends React.Component{
render(){
return(
<View style={styles.container}>
<TouchableWithoutFeedback
onPress={()=>{alert('响应')}}
pressRetentionOffset={{top:100,bottom:100,left:50,right:50}}
>
<View style={[styles.touchable,styles.viewBox]}>
<Text style={styles.test}>TEST</Text>
</View>
</TouchableWithoutFeedback>
</View>
)
}
}
效果:
- press延迟属性
delayPressIn//单位是毫秒,从触摸操作开始到被调用的延迟onPressIn。
delayPressOut//单位是毫秒,从触摸操作结束开始到被调用的延迟onPressOut。
delayLongPress//单位是毫秒,onPressIn开始从,到被调用的延迟onLongPress。
export default class Test extends React.Component{
render(){
return(
<View style={styles.container}>
<TouchableWithoutFeedback
onPressIn={()=>{alert('pressIn')}}
onPressOut={()=>{alert('pressOut')}}
delayPressIn={300}
delayPressOut={3000}
>
<View style={[styles.touchable,styles.viewBox]}>
<Text style={styles.test}>TEST</Text>
</View>
</TouchableWithoutFeedback>
</View>
)
}
}
效果:
- 其他属性
disabled//布尔值,禁止一切点击事件
accessible//设置当前组件是否可以访问
accessibilityTraits//设置访问特征
accessibilityComponentType//设置可访问的组件类型
2. TouchableOpacity
当按下的时候,封装的视图的不透明度会降低。这个过程并不会真正改变视图层级,情况大部分很下容易添加到应用中而不会带来一些奇怪的副作用。
TouchableOpacity继承了TouchableWithoutFeedback组件的所有属性,下面是一下其自身独有属性:
- activeOpacity
export default class Test extends React.Component{
render(){
return(
<View style={styles.container}>
<TouchableOpacity
activeOpacity={0.5}
>
<View style={[styles.touchable,styles.viewBox]}>
<Text style={styles.test}>TEST</Text>
</View>
</TouchableOpacity>
</View>
)
}
}
效果:
- setOpacityTo
export default class Test extends React.Component{
render(){
return(
<View style={styles.container}>
<TouchableOpacity
ref='opacity'
>
<View style={[styles.touchable,styles.viewBox]}>
<Text style={styles.test}>TEST</Text>
</View>
</TouchableOpacity>
<Button
style={{marginTop:20}}
title='测试opacity'
//组件方法调用
onPress={()=>{this.refs.opacity.setOpacityTo(0.1,1000)}}
/>
</View>
)
}
}
效果:
3. TouchableHighlight
按下组件视图的时候,封装的视图的不透明度会降低,同时会有一个底层的颜色透过而被用户看到,使得视图变暗或变亮。
TouchableHightlight继承了TouchableWithoutFeedback组件的所有属性,下面会是一些本组件常用属性。
TouchableHighlight只支持一个子节点,如果你需要设置多个子视图组件,就需要使用View节点进行包装。
activeOpacity
可参考TouchableOpacity组件属性。
underlayColor
底层颜色设置
export default class Test extends React.Component{
render(){
return(
<View style={styles.container}>
<TouchableHighlight
activeOpacity={0.5}
underlayColor='#f00'
//注意onPress必须存在,即使为空函数,否则underlayColor无效果
onPress={()=>{}}
>
<View style={[styles.touchable,styles.viewBox]}>
<Text style={styles.test}>TEST</Text>
</View>
</TouchableHighlight>
</View>
)
}
}
效果:
- 底色回调
onShowUnderlay//底色出现时回调
onHideUnderlay//底色消失时回调
export default class Test extends React.Component{
render(){
return(
<View style={styles.container}>
<TouchableHighlight
activeOpacity={0.5}
underlayColor='#f00'
onPress={()=>{}}
onHideUnderlay={()=>{alert('hideUnderlay')}}
onShowUnderlay={()=>{alert('showUnderlay')}}
>
<View style={[styles.touchable,styles.viewBox]}>
<Text style={styles.test}>TEST</Text>
</View>
</TouchableHighlight>
</View>
)
}
}
效果:
4. TouchableNativeFeedback
同样的,该组件继承了TouchableWithoutFeedback组件的所有属性;
为了支持Android5.0新增的触控反馈,React Native加入了TouchableNativeFeedback组件,TouchableNativeFeedback在TouchableWithoutFeedback所支持的属性的基础上增加了按下去的水波纹效果。我们可以通过background属性来自定义原生触摸操作反馈的背景。
background backgroundPropType 该用来设置背景资源的类型,该属性会传入一个type属性和依赖的额外资源的data的对象。官方推荐采用如下的静态方法来进行生成该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+才可以使用