awaitPointerEventScope 二指縮放
使用模擬器,按下ctrl + 滑鼠左鍵,即可模擬二指縮放大小。
在 Jetpack Compose 中,awaitPointerEventScope 是 pointerInput 用於處理手勢和手指頭的交互動作。
awaitPointerEvent是一個suspend function,是協程函式,用於監控手勢與手指頭的交互動作。
使用while(true) 持續監聽手指碰觸螢幕,當Compose Tree被記憶體回收,就會停止監控。
1
2
3
4
5
Modifier
.awaitPointerEventScope {
while (true) {
}
}
判斷幾個手指頭在碰觸螢幕。
event.changes.size
取得每一個手指頭碰觸螢幕的座標
手指1
event.changes[0].position
手指2
event.changes[1].position


放大縮小程式碼:
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
56
57
58
59
60
61
62
63
64
@Composable
fun ZoomExample1() {
// 預設1f是無放大縮小
var scale by remember { mutableStateOf(1f) }
// 存放手指1座標
var offset1 by remember { mutableStateOf(Offset.Zero) }
// 存放手指2座標
var offset2 by remember { mutableStateOf(Offset.Zero) }
// 追蹤上一次的兩指距離
var lastDistance by remember { mutableFloatStateOf(0f) }
Box(
modifier = Modifier
.fillMaxSize()
.pointerInput(Unit) {
awaitPointerEventScope {
while (true) {
// 判斷是否有手指碰觸螢幕
val event = awaitPointerEvent()
// debug
println("size = ${event.changes.size}")
// 有沒有2隻手指碰觸
if (event.changes.size >= 2) {
// 取得手指1座標
offset1 = event.changes[0].position
// 取得手指2座標
offset2 = event.changes[1].position
// 計算二個座標距離
val x_dis = offset1.x - offset2.x
val y_dis = offset1.y - offset2.y
val cur_dis = sqrt(x_dis * x_dis + y_dis * y_dis)
if (lastDistance > 0) {
// 目前距離 除 原本距離
val scaleChange = cur_dis / lastDistance
// coerceIn(最小值,最大值)
// 縮放最小值不得低於0.5f,最大值不得大於3f
scale = (scale * scaleChange).coerceIn(0.5f,3f)
// 指派目前的距離至 lastDistance
lastDistance = cur_dis
} else {
lastDistance = cur_dis
}
} else {
// 若變成1隻手指觸碰,把lastDistance恢復原狀
lastDistance = 0f
}
}
}
}
) {
Column {
Text("offset1 x= ${offset1.x.toInt()} y = ${offset1.y.toInt()}")
Text("offset2 x= ${offset2.x.toInt()} y = ${offset2.y.toInt()}")
Box(modifier = Modifier
.size(200.dp)
// 放大縮小
.graphicsLayer {
scaleX = scale
scaleY = scale
}
.background(Color.Blue)
)
}
}
}