本文是RN(React Native)系列教程第一篇,当然也要给自己的群做个广告:
React Native @Himi :126100395 刚创建的群,欢迎一起学习、讨论、进步。
本文主要讲解两点:
1. PanResponder:触摸事件,用以获取用户手指所在屏幕的坐标(x,y)或触发、或滑动、或抬起几种事件通知。
2. Touchable:React为我们封装好的触摸组件。引用原文:“响应系统用起来可能比较复杂。所以我们提供了一个抽象的Touchable
实现,用来做“可触控”的组件。这一实现利用了响应系统,使得你可以简单地以声明的方式来配置触控处理。”
一:触摸事件各事件响应与坐标获取
1. 在import React 中添加要使用的触摸组件:
1
2
3
4
5
|
import
React
,
{
.
.
.
PanResponder
,
//触摸必要的组件
.
.
.
}
from
'react-native'
;
|
2. 声明:
1
2
3
4
5
6
7
8
|
constructor
(
props
)
{
super
(
props
)
;
this
.
state
=
{
eventName
:
''
,
pos
:
''
,
}
;
this
.
myPanResponder
=
{
}
}
|
这里先声明了两个变量posX,posY用于显示坐标用,另外声明了一个 myPanResponder 用于后面的触摸事件。
3. 创建、设置与响应
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
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进行设置
1
|
{
.
.
.
this
.
myPanResponder
.
panHandlers
}
|
5. 完善Render函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
render
(
)
{
return
(
<
View
style
=
{
styles
.
himiViewStyle
}
{
.
.
.
this
.
myPanResponder
.
panHandlers
}
>
<
Text
style
=
{
styles
.
himiTextStyle
}
>
Himi
React
Native
教程
<
/
Text
>
<
View
style
=
{
styles
.
container
}
>
<
Text
style
=
{
styles
.
text
}
>
{
this
.
state
.
eventName
}
<
/
Text
>
<
Text
style
=
{
styles
.
text
}
>
{
this
.
state
.
pos
}
<
/
Text
>
<
/
View
>
<
/
View
>
)
}
|
6.用到的布局和样式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
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
,
}
,
}
)
;
|
效果如下:(点击查看动态效果)
如上是第一种形式,下面我们简单说下如何使用第二种形式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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
|
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的四种组件
1
2
3
4
5
6
7
8
9
10
|
import
React
,
{
.
.
.
Image
,
Alert
,
TouchableHighlight
,
TouchableNativeFeedback
,
TouchableOpacity
,
TouchableWithoutFeedback
,
.
.
.
}
from
'react-native'
;
|
Himi这里还添加了Image和Alert两个组件:
Image 是图片组件,这里是为了测试效果,将Touchable发生在图片
Alert 弹窗提示组件,是为了通过弹窗,更好的展示出事件响应效果
2. 在Render添加如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
<
View
style
=
{
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之外的三种形式。
根据反馈的形式,大家可以自行设置其透明度、背景色、样式等。
效果图如下:(点击查看动态图)
注意:Touchable 组件系列都只能包含一个子组件,也就是说你想多个,可以嵌套View组件来实现。如:
1
2
3
4
5
6
|
<
TouchableHighlight
>
<
View
>
<
Text
>
t1
<
/
Text
>
<
Text
>
t2
<
/
Text
>
<
/
View
>
<
/
TouchableHighlight
>
|