App Inventor 2 手势识别扩展教程 - GestureDetector

« 返回首页

概述

App Inventor 2的Canvas和Screen只有基本的Touch/Dragged/Fling事件。手势识别扩展(GestureDetector)可以识别更丰富的手势:

手势 内置支持 扩展支持
单击 ✅ Touched
双击 ✅ onDoubleTap
长按 ✅ onLongPress
滑动 ✅ Flung ✅ onFling(更精确)
缩放(捏合) ✅ onScale
滚动 部分(Dragged) ✅ onScroll
多点触控 ✅ Multitouch扩展

已有文档参考

  • other/extensionsGestures.md — 手势扩展基础文档
  • other/extensionsMultitouch.md — 多点触控扩展
  • other/extensionsRotation.md — 旋转手势扩展

本文在已有文档基础上,补充具体的使用场景和集成方案。

GestureDetector扩展

导入扩展

  1. 下载 GestureDetector扩展(.aix文件)
  2. Designer → Extension → Import Extension → 选择.aix

核心事件

当 GestureDetector1.双击(X, Y)
  ' 双击触发
  标签_状态.文本 = "双击 @ " & X & "," & Y

当 GestureDetector1.长按(X, Y)
  ' 长按触发
  标签_状态.文本 = "长按 @ " & X & "," & Y

当 GestureDetector1.滑动(起点X, 起点Y, 终点X, 终点Y, 速度X, 速度Y)
  ' 滑动方向判断
  设 dX = 终点X - 起点X
  设 dY = 终点Y - 起点Y
  
  如果 数学.绝对值(dX) > 数学.绝对值(dY)
    如果 dX > 0
      标签_状态.文本 = "👉 右滑"
    否则
      标签_状态.文本 = "👈 左滑"
  否则
    如果 dY > 0
      标签_状态.文本 = "👇 下滑"
    否则
      标签_状态.文本 = "👆 上滑"

关联组件

GestureDetector需要关联到一个可视组件(如Canvas或Image):

当 Screen1.初始化
  调用 GestureDetector1.设置目标组件(Canvas1)

实战案例:图片浏览器手势

功能

  • 左右滑动切换图片
  • 双击放大/缩小
  • 长按保存图片
  • 上下滑动显示/隐藏工具栏
设 图片列表 = ["pic1.png", "pic2.png", "pic3.png", "pic4.png"]
设 当前索引 = 1
设 是否放大 = false

当 Screen1.初始化
  调用 GestureDetector1.设置目标组件(Image1)
  设 Image1.图片 = 列表第1项(图片列表)

当 GestureDetector1.滑动(起点X, 起点Y, 终点X, 终点Y, 速度X, 速度Y)
  设 dX = 终点X - 起点X
  如果 数学.绝对值(dX) > 50  ' 滑动距离阈值
    如果 dX > 0 且 当前索引 > 1
      设 当前索引 = 当前索引 - 1
      设 Image1.图片 = 列表第当前索引项(图片列表)
    否则 如果 dX < 0 且 当前索引 < 列表长度(图片列表)
      设 当前索引 = 当前索引 + 1
      设 Image1.图片 = 列表第当前索引项(图片列表)
    标签_页码.文本 = 当前索引 & "/" & 列表长度(图片列表)

当 GestureDetector1.双击(X, Y)
  如果 是否放大
    设 Image1.宽度 = 90 百分比
    设 Image1.高度 = 自动
    设 是否放大 = false
  否则
    设 Image1.宽度 = 200 百分比
    设 Image1.高度 = 200 百分比
    设 是否放大 = true

当 GestureDetector1.长按(X, Y)
  调用 文件工具.保存到相册(Image1.图片)
  调用 通知.显示信息("已保存", "图片已保存到相册")

实战案例:手势密码锁

功能

  • 在Canvas上画手势路径
  • 记录触摸经过的格子
  • 验证手势密码
设 网格大小 = 3  ' 3x3网格
设 格子坐标 = 创建空列表
设 手势路径 = 创建空列表
设 正在画 = false
设 正确密码 = "1-2-3-6-9"  ' 示例密码路径

当 Screen1.初始化
  ' 计算格子中心坐标
  设 格子宽 = Canvas1.宽度 / 网格大小
  设 格子高 = Canvas1.高度 / 网格大小
  设 i = 0
  当 i < 9
    设 行 = 数学.向下取整(i / 网格大小)
    设 列 = i 模 网格大小
    设 中心X = 列 * 格子宽 + 格子宽 / 2
    设 中心Y = 行 * 格子高 + 格子高 / 2
    设 格子坐标 = 添加列表项(格子坐标, 创建字典("id" → (i+1), "x" → 中心X, "y" → 中心Y))
    设 i = i + 1
  绘制网格()

当 Canvas1.触摸(触摸, X, Y)
  设 正在画 = true
  设 手势路径 = 创建空列表
  调用 检查格子(X, Y)

当 Canvas1.拖动(被拖动, 起X, 起Y, 当X, 当Y, 上X, 上Y)
  如果 被拖动
    调用 检查格子(当X, 当Y)
    ' 画线连接
    调用 Canvas1.画线(上X, 上Y, 当X, 当Y)

定义 检查格子(X, Y)
  设 i = 1
  当 i ≤ 列表长度(格子坐标)
    设 格子 = 列表第i项(格子坐标)
    设 格X = 从字典 格子 获取 "x"
    设 格Y = 从字典 格子 获取 "y"
    设 格ID = 从字典 格子 获取 "id"
    设 距离 = 数学.平方根((X-格X)^2 + (Y-格Y)^2)
    如果 距离 < 40 且 非 (格ID 是否在 手势路径 中)
      设 手势路径 = 添加列表项(手势路径, 格ID)
      ' 高亮选中的格子
      调用 Canvas1.画圆(格X, 格Y, 30, 绿色)
    设 i = i + 1

当 按钮_验证.被点击
  设 路径文本 = 列表转文本(手势路径, "-")
  如果 路径文本 = 正确密码
    标签_结果.文本 = "✅ 密码正确"
    调用 打开另一个屏幕("Screen_Main")
  否则
    标签_结果.文本 = "❌ 密码错误"

Multitouch多点触控

参考已有文档 other/extensionsMultitouch.md,此处补充关键用法:

设 手指计数 = 0

当 Multitouch1.触摸开始(指针ID, X, Y)
  设 手指计数 = 手指计数 + 1
  标签_手指.文本 = "触摸点:" & 手指计数

当 Multitouch1.触摸移动(指针ID, X, Y)
  ' 多指拖拽处理
  如果 手指计数 = 2
    ' 双指缩放
    设 距离 = 计算两点距离(手指1X, 手指1Y, 手指2X, 手指2Y)
    设 缩放比 = 距离 / 初始距离
    设 Image1.宽度 = 初始宽度 * 缩放比

当 Multitouch1.触摸结束(指针ID, X, Y)
  设 手指计数 = 手指计数 - 1

常见问题

Q1: 手势扩展和Canvas事件冲突?

设置优先级:手势扩展和Canvas事件可能同时触发。解决:

  • 用手势扩展处理复杂手势(双击、长按)
  • 用Canvas事件处理绘制相关
  • 设置标志变量控制

Q2: 手势识别灵敏度如何调整?

大多数手势扩展有阈值参数:

  • CONFIRM_THRESHOLD — 确认阈值
  • VELOCITY_THRESHOLD — 速度阈值
  • 根据实际体验微调

Q3: 如何实现下拉刷新?

当 GestureDetector1.滑动(起点X, 起点Y, 终点X, 终点Y, 速度X, 速度Y)
  设 dY = 终点Y - 起点Y
  如果 dY > 100 且 速度Y > 500  ' 下拉距离够且速度够
    ' 触发刷新
    调用 刷新数据()

总结

手势 方案 推荐扩展
单击 内置Touched 不需要
双击 GestureDetector GestureDetector
长按 GestureDetector GestureDetector
滑动方向 内置Flung或扩展 GestureDetector
缩放 Multitouch Multitouch
旋转 Rotation扩展 Rotation
多指 Multitouch Multitouch

版权声明:MIT App Inventor 官方文档采用 CC BY-SA 4.0 授权,本文档由 ai2claw 🐝 整理。

文档反馈