
package com.wztool.project.util
import android.annotation.SuppressLint
import android.view.MotionEvent
import android.view.View
import kotlin.math.abs
import kotlin.math.atan2
/**
* 手势使用
* @author zph
* @date 2025/04/09
*/
object GestureUtils {
@SuppressLint("ClickableViewAccessibility")
fun setGestureListener(view: View, listener: (gesture: Int) -> Unit) {
view.setOnTouchListener { v, event ->
//判断触摸路径横竖撇捺
when (event.action) {
MotionEvent.ACTION_DOWN -> {
handleTouchDown(event.x, event.y)
}
MotionEvent.ACTION_UP -> {
handleTouchUp(event.x, event.y, listener)
}
else -> {
// 处理其他触摸事件(如多点触控等)
return@setOnTouchListener false
}
}
return@setOnTouchListener false
}
}
private var startX = 0f
private var startY = 0f
private var isHorizontal = false // 是否为横向手势
private var isVertical = false // 是否为竖向手势
private var isLeftSlash = false // 是否为撇
private var isRightSlash = false // 是否为捺
// 提取触摸开始的逻辑
private fun handleTouchDown(x: Float, y: Float) {
synchronized(this) { // 确保线程安全
startX = x
startY = y
}
}
// 提取触摸结束的逻辑
private fun handleTouchUp(x: Float, y: Float, listener: (gesture: Int) -> Unit) {
val deltaX = x - startX
val deltaY = y - startY
val absDeltaX = abs(deltaX)
val absDeltaY = abs(deltaY)
// absDeltaX.log("FragWord absDeltaX")
// absDeltaY.log("FragWord absDeltaY")
determineGesture(absDeltaX, absDeltaY, deltaX, deltaY)
synchronized(this) { // 确保线程安全
// when {
// isHorizontal -> "横向手势".log("FragWord")
// isVertical -> "竖向手势".log("FragWord")
// isLeftSlash -> "撇向手势".log("FragWord")
// isRightSlash -> "捺向手势".log("FragWord")
// }
when {
isHorizontal -> listener(1)
isVertical -> listener(2)
isLeftSlash -> listener(3)
isRightSlash -> listener(4)
else -> listener(0)
}
resetGestureState() // 重置手势状态
}
}
// 判断手势类型
private fun determineGesture(absDeltaX: Float, absDeltaY: Float, deltaX: Float, deltaY: Float) {
if (!isValidGesture(absDeltaX, absDeltaY)) return
val angle = Math.toDegrees(atan2(deltaY.toDouble(), deltaX.toDouble()))
angle.log("FragWord angle")
when (angle) {
in -15.0..15.0 -> isHorizontal = true
in 75.0..105.0 -> isVertical = true
in 15.0..75.0 -> isRightSlash = true
in -75.0..-15.0 -> isLeftSlash = true
in 105.0..170.0 -> isLeftSlash = true
in -170.0..-105.0 -> isRightSlash = true
}
}
// 校验手势参数是否有效
private fun isValidGesture(absDeltaX: Float, absDeltaY: Float): Boolean {
return absDeltaX.isFinite() && absDeltaY.isFinite()
}
// 重置手势状态
private fun resetGestureState() {
isHorizontal = false
isVertical = false
isLeftSlash = false
isRightSlash = false
}
}