昨天我們用了上下滑的事件來觸發頁面跳轉的功能,今天我們來拓展一下這方面的內容,我弄了一個教學用的程式來做一些簡單的示範
程式碼如下
package com.example.myapplication
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.text.BasicText
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.gestures.detectTransformGestures
import androidx.compose.foundation.gestures.detectDragGestures
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.graphics.graphicsLayer
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MultiGestureTutorial()
}
}
}
@Composable
fun MultiGestureTutorial() {
var boxContent by remember { mutableStateOf("點擊、長按、雙擊、拖動、縮放或旋轉方塊") }
var scale by remember { mutableStateOf(1f) } // 用於縮放
var rotation by remember { mutableStateOf(0f) } // 用於旋轉
var offsetX by remember { mutableStateOf(0f) } // 用於拖動
var offsetY by remember { mutableStateOf(0f) } // 用於拖動
Box(
modifier = Modifier
.fillMaxSize()
.background(Color.White)
) {
// 使用 pointerInput,整合各種手勢處理邏輯
Box(
modifier = Modifier
.size(200.dp)
.offset { IntOffset(offsetX.toInt(), offsetY.toInt()) } // 拖動效果
.background(Color.Gray)
.pointerInput(Unit) {
// 偵測縮放與旋轉手勢
detectTransformGestures { _, pan, zoom, rotationChange ->
scale *= zoom // 更新縮放比例
rotation += rotationChange // 更新旋轉角度
boxContent = "縮放: ${String.format("%.2f", scale)}, 旋轉: ${String.format("%.2f", rotation)}°"
}
}
.pointerInput(Unit) {
// 偵測點擊、雙擊與長按手勢
detectTapGestures(
onTap = { offset ->
boxContent = "單擊觸發,位置: $offset"
},
onDoubleTap = { offset ->
boxContent = "雙擊觸發,位置: $offset"
},
onLongPress = { offset ->
boxContent = "長按觸發,位置: $offset"
}
)
}
.pointerInput(Unit) {
// 偵測拖動手勢
detectDragGestures { change, dragAmount ->
offsetX += dragAmount.x
offsetY += dragAmount.y
boxContent = "拖動中..."
}
}
.graphicsLayer(
scaleX = scale,
scaleY = scale,
rotationZ = rotation
)
)
BasicText(
text = boxContent,
modifier = Modifier.background(Color.Transparent),
style = MaterialTheme.typography.bodyLarge
)
}
}
@Preview(showBackground = true)
@Composable
fun MultiGestureTutorialPreview() {
MultiGestureTutorial()
}
這個程式的目的是演示如何在Jetpack Compose中實現基本的觸控手勢,包括拖動、縮放、旋轉,以及單擊、雙擊和長按等功能。在這段程式中,我們使用了多種手勢偵測器來處理使用者的觸控行為,並即時更新畫面上的方塊,讓我們能夠直觀地看到每個手勢的效果。
首先,我們定義了一個Box,用來承載可以進行手勢互動的灰色方塊。這個方塊可以根據使用者的手勢進行移動、縮放和旋轉。方塊的外觀會即時根據手勢發生變化。手勢的核心處理是透過pointerInput
函數來完成的。在這個函數中,我們可以定義不同的手勢邏輯,來捕捉使用者的觸控動作。
首先,我們使用detectTransformGestures
來偵測縮放和旋轉的手勢。這個函數會捕捉到多點觸控時的縮放比例 (zoom) 和旋轉角度(rotationChange),並且將這些值應用到方塊的scale
和rotation
屬性上。當使用者用雙指捏合時,方塊會根據縮放比例放大或縮小;當雙指旋轉時,方塊也會跟著旋轉。這些變化透過graphicsLayer
來實現,讓方塊的外觀即時更新。
接下來,我們使用detectTapGestures
來處理單擊、雙擊和長按的手勢,我們針對不同的點擊行為設定回調。例如,當使用者單擊方塊時,會觸發onTap
回調,並顯示單擊的位置;雙擊會觸發onDoubleTap
,而長按則觸發 onLongPress
。這些手勢被偵測到後,我們會更新boxContent
,即時將手勢結果顯示在介面上。
此外拖動的功能是透過 detectDragGestures 來實現的。當使用者按住並拖動方塊時,方塊的位置會根據拖動的距離進行更新,這是通過改變 offsetX 和 offsetY 來完成的。這樣,方塊就可以隨著使用者的手勢在螢幕上移動。
下面有示範的影片
今天有事情出去了一趟文章的內容比較水一點,補充一下昨天沒講到的東西,今天的內容就到這邊,我們明天再見,