Android 手势判断(横竖撇捺)

在这里插入图片描述

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
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

魑魅魍魉9527

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值