Android多点触控问题

06-01 1209阅读

触摸事件类型

单点触控相关:

  • ACTION_DOWN

    当用户首次触摸屏幕时触发,表示触摸的开始。通常是触摸事件的起点。

  • ACTION_MOVE

    当用户在屏幕上移动手指时触发,表示触摸点位置发生变化。

  • ACTION_UP

    当用户抬起手指时触发,表示触摸结束。

  • ACTION_CANCEL

    当触摸事件被取消时触发,例如父 View 拦截了事件或系统中止了触摸。

    多点触控相关:

    • ACTION_POINTER_DOWN

      当屏幕上已有触摸点时,另一个手指按下触发,表示新增了一个触摸点。

    • ACTION_POINTER_UP

      当屏幕上有多个触摸点时,其中一个手指抬起触发,表示某个触摸点结束。

      多点触控处理相关方法

      • event.getActionMasked():返回当前的触摸事件类型(包含单点触控和多点触控)。
      • event.getActionIndex():返回多点触控事件中当前新增触摸点或当前移除触摸点的索引(适用于ACTION_POINTER_DOWN和ACTION_POINTER_UP多点触控相关事件)。
      • getPointerId(int index):根据指定索引返回对应触摸点的唯一ID。
      • getX(int index)和getY(int index):返回指定索引的触摸点的X和Y坐标。
      • getPointerCount():返回当前触摸点的数量。
      • findPointerIndex(int pointerId):根据ID查找触摸点当前索引。

        触摸点的索引与ID

        • 索引:触摸点的编号,从0开始,最大值为getPointerCount()-1。但索引是动态的,会因触摸点的抬起而改变。
        • ID:每个触摸点的唯一标识符,在其生命周期内固定不变。因此,ID是跟踪特定触摸点的可靠依据。

          例如:一个手指按下,索引为0,ID为0。第二个手指按下,索引为1,ID为1。第一个手指抬起,那么第二个手指的索引变为0,但ID仍为1。

          处理多点触控的步骤

          1.记录新触摸点

          ACTION_DOWN:第一个触摸点按下,记录第一个触摸点的ID和位置(此时ID为0),并添加到Map中。

          ACTION_POINTER_DOWN:新增触摸点按下,记录其ID和位置(此时通过getActionIndex()获取新增触摸点的索引,然后将该索引传入getPointerId()中得到对应的触摸点ID;将索引传入getX、getY中得到触摸点位置),并添加到Map中。

          2.更新触摸点

          ACTION_MOVE:遍历所有触摸点(i in 0..getPointerCount()-1),更新它们的当前位置。

          3.移除触摸点

          ACTION_POINTER_UP:某个触摸点抬起,获取该触摸点ID(此时通过getActionIndex()获取移除触摸点的索引,然后将该索引传入getPointerId()中得到对应的触摸点ID),在Map中移除。

          ACTION_UP:最后一个触摸点抬起,结束整个触摸过程。

          实际代码理解

          class TouchView(context: Context) : View(context) {
              // 使用MutableMap存储触摸点ID和对应的(X, Y)坐标
              private val touchPoints = mutableMapOf()
              private val paint = Paint().apply {
                  color = 0xFF0000FF.toInt() // 蓝色
                  style = Paint.Style.FILL
              }
              override fun onTouchEvent(event: MotionEvent): Boolean {
                  when (event.actionMasked) {
                      MotionEvent.ACTION_DOWN -> {
                          // 第一个触摸点按下
                          val id = event.getPointerId(0)
                          val x = event.getX(0)
                          val y = event.getY(0)
                          touchPoints[id] = Pair(x, y)
                      }
                      MotionEvent.ACTION_POINTER_DOWN -> {
                          // 新的触摸点按下
                          val index = event.actionIndex
                          val id = event.getPointerId(index)
                          val x = event.getX(index)
                          val y = event.getY(index)
                          touchPoints[id] = Pair(x, y)
                      }
                      MotionEvent.ACTION_MOVE -> {
                          // 触摸点移动,更新所有触摸点位置
                          for (i in 0 until event.pointerCount) {
                              val id = event.getPointerId(i)
                              val x = event.getX(i)
                              val y = event.getY(i)
                              touchPoints[id] = Pair(x, y)
                          }
                      }
                      MotionEvent.ACTION_POINTER_UP -> {
                          // 某个触摸点抬起,移除该触摸点
                          val index = event.actionIndex
                          val id = event.getPointerId(index)
                          touchPoints.remove(id)
                      }
                      MotionEvent.ACTION_UP -> {
                          // 最后一个触摸点抬起,清空Map
                          touchPoints.clear()
                      }
                      MotionEvent.ACTION_CANCEL -> {
                          // 触摸事件取消,清空Map
                          touchPoints.clear()
                      }
                  }
                  // 触发重绘
                  invalidate()
                  return true
              }
              override fun onDraw(canvas: Canvas) {
                  super.onDraw(canvas)
                  // 绘制每个触摸点
                  for ((_, point) in touchPoints) {
                      canvas.drawCircle(point.first, point.second, 50f, paint)
                  }
              }
          }

          总结

          多点触控的处理是通过 onTouchEvent 方法中的事件(如 ACTION_DOWN、ACTION_POINTER_DOWN、ACTION_MOVE、ACTION_POINTER_UP、ACTION_UP),利用触摸点的唯一 ID 来管理其记录、更新和移除。

          Android多点触控问题
          (图片来源网络,侵删)
          Android多点触控问题
          (图片来源网络,侵删)
          Android多点触控问题
          (图片来源网络,侵删)
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

目录[+]

取消
微信二维码
微信二维码
支付宝二维码