手势识别官方教程(5)多点触摸的处理

Handling Multi-Touch Gestures

  A multi-touch gesture is when multiple pointers (fingers) touch the screen at the same time. This lesson describes how to detect gestures that involve multiple pointers.

Track Multiple Pointers

  When multiple pointers touch the screen at the same time, the system generates the following touch events:

  当有多个手指同时按下屏幕时,产生下列事件。
  • ACTION_DOWN—For the first pointer that touches the screen. This starts the gesture. The pointer data for this pointer is always at index 0 in the MotionEvent.
    第一个手指按下
  • ACTION_POINTER_DOWN—For extra pointers that enter the screen beyond the first. The pointer data for this pointer is at the index returned by getActionIndex().
    其它手指按下,用index得到
  • ACTION_MOVE—A change has happened during a press gesture.
    在按住屏幕时手指位置发生变化时
  • ACTION_POINTER_UP—Sent when a non-primary pointer goes up.
    当其它手指离开屏幕时
  • ACTION_UP—Sent when the last pointer leaves the screen.
    最后一个手指离开屏幕

  You keep track of individual pointers within a MotionEvent via each pointer's index and ID:

  多点触摸时,每个手指都有对应的index和id,可以利用它们得到对应的手指数据,它们的含义如下:
  • Index: A MotionEvent effectively stores information about each pointer in an array. The index of a pointer is its position within this array. Most of the MotionEvent methods you use to interact with pointers take the pointer index as a parameter, not the pointer ID.
    MotionEvent 把每个手指的数据存在一个数组中,要用index来得到相应的手指数据。
  • ID: Each pointer also has an ID mapping that stays persistent across touch events to allow tracking an individual pointer across the entire gesture.

  The order in which individual pointers appear within a motion event is undefined. Thus the index of a pointer can change from one event to the next, but the pointer ID of a pointer is guaranteed to remain constant as long as the pointer remains active. Use the getPointerId() method to obtain a pointer's ID to track the pointer across all subsequent motion events in a gesture. Then for successive motion events, use the findPointerIndex() method to obtain the pointer index for a given pointer ID in that motion event. For example:

复制代码
 1 private int mActivePointerId;
 2  
 3 public boolean onTouchEvent(MotionEvent event) {
 4     ....
 5     // Get the pointer ID
 6     mActivePointerId = event.getPointerId(0);
 7 
 8     // ... Many touch events later...
 9 
10     // Use the pointer ID to find the index of the active pointer 
11     // and fetch its position
12     int pointerIndex = event.findPointerIndex(mActivePointerId);
13     // Get the pointer's current position
14     float x = event.getX(pointerIndex);
15     float y = event.getY(pointerIndex);
16 }
复制代码

Get a MotionEvent's Action

  You should always use the method getActionMasked() (or better yet, the compatability version MotionEventCompat.getActionMasked()) to retrieve the action of a MotionEvent. Unlike the older getAction() method, getActionMasked() is designed to work with multiple pointers. It returns the masked action being performed, without including the pointer index bits. You can then use getActionIndex() to return the index of the pointer associated with the action. This is illustrated in the snippet below.

注意多用 getActionMasked() 而少用 getAction() 前者支持多点触摸。

  Note: This example uses the MotionEventCompat class. This class is in the Support Library. You should use MotionEventCompat to provide the best support for a wide range of platforms. Note that MotionEventCompat is not a replacement for the MotionEvent class. Rather, it provides static utility methods to which you pass your MotionEvent object in order to receive the desired action associated with that event.

复制代码
 1 int action = MotionEventCompat.getActionMasked(event);
 2 // Get the index of the pointer associated with the action.
 3 int index = MotionEventCompat.getActionIndex(event);
 4 int xPos = -1;
 5 int yPos = -1;
 6 
 7 Log.d(DEBUG_TAG,"The action is " + actionToString(action));
 8             
 9 if (event.getPointerCount() > 1) {
10     Log.d(DEBUG_TAG,"Multitouch event"); 
11     // The coordinates of the current screen contact, relative to 
12     // the responding View or Activity.  
13     xPos = (int)MotionEventCompat.getX(event, index);
14     yPos = (int)MotionEventCompat.getY(event, index);
15 
16 } else {
17     // Single touch event
18     Log.d(DEBUG_TAG,"Single touch event"); 
19     xPos = (int)MotionEventCompat.getX(event, index);
20     yPos = (int)MotionEventCompat.getY(event, index);
21 }
22 ...
23 
24 // Given an action int, returns a string description
25 public static String actionToString(int action) {
26     switch (action) {
27                 
28         case MotionEvent.ACTION_DOWN: return "Down";
29         case MotionEvent.ACTION_MOVE: return "Move";
30         case MotionEvent.ACTION_POINTER_DOWN: return "Pointer Down";
31         case MotionEvent.ACTION_UP: return "Up";
32         case MotionEvent.ACTION_POINTER_UP: return "Pointer Up";
33         case MotionEvent.ACTION_OUTSIDE: return "Outside";
34         case MotionEvent.ACTION_CANCEL: return "Cancel";
35     }
36     return "";
37 }
复制代码

  For more discussion of multi-touch and some examples, see the lesson Dragging and Scaling.

 

posted @   f9q  阅读(408)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
点击右上角即可分享
微信分享提示