MotionEvent(二) 多點觸摸

來源:互聯網
上載者:User

多點觸摸和單點觸摸的機制一樣,都是為觸摸事件建立MotionEvent對象,並將這些MotionEvent對象傳遞給各種方法。

多點觸摸的2個重要概念是指標索引和指標ID

指標索引:android把多點觸摸時的一個手指抽象成一個“指標”,這個指標有其索引,從0開始。這個索引分配給對應的手指之後,值是會隨著手指數量的增減而改變的。如果同時有2根手指在螢幕上,第一根手指指標索引為0,第二根為1,如果第一根手指離開螢幕,第二根的指標索引變為0,因為此刻螢幕上只有1根手指

指標ID:唯一標識一根手指的id,相當於表的主鍵,這個值和索引不一樣,是不會變的。

指標索引和指標ID的關係就像是資料庫表中的記錄的行號和其主鍵,刪除一條記錄,其他記錄的行號會發生變化,但是他們的ID是唯一的。

對於多點觸摸,MotionEvent中常用到的方法:

getPointerCount():返回MotionEvent中表示了多少手指數

getPointerId(int pointerIndex): 返回指標索引關聯的指標ID

getY(int pointerIndex):返回指定指標索引的當前的Y座標位置

getX(int pointerIndex):返回指定指標索引的當前的X座標位置

getHistorySize():返回某跟手指觸摸事件的曆史位置的記錄數

getHistoricalX (int pointerIndex, int pos):返回指定指標索引的手指上一次的X座標位置,只針對移動事件。參數pos是指第幾箇舊位置,這個值不能超過getHistorySize()返回的值
getHistoricalY (int pointerIndex, int pos):返回指定指標索引的手指上一次的Y座標位置,只針對移動事件。參數pos是指第幾箇舊位置,這個值不能超過getHistorySize()返回的值

測試代碼:

布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context=".MainActivity"    android:id="@+id/relativelayout"     >    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="@string/hello_world" /></RelativeLayout>

MainActivity.java:

public class MainActivity extends Activity implements OnTouchListener{@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);RelativeLayout r = (RelativeLayout)findViewById(R.id.relativelayout);r.setOnTouchListener(this);}@Overridepublic boolean onTouch(View v, MotionEvent event) {StringBuilder result = new StringBuilder(500);//手指的動作int action = event.getAction();//幾根手指int points = event.getPointerCount();result.append("action:" + action).append(",point_count:"+points);//輸出此刻所有手指的狀態for (int i = 0; i < points; i++) {result.append(",index:").append(i).append(",id:"+ event.getPointerId(i));result.append(",getX:").append(event.getX(i)).append(",getY:").append(event.getY(i));}Log.v("test", "---------------------------------------");Log.v("test", result.toString());return true;}}

現在運行程式,然後放上一根手指在螢幕上,再放一根上去。再依次鬆開手指,查看日誌輸出

06-18 23:55:35.612: V/test(10138): ---------------------------------------
06-18 23:55:35.612: V/test(10138): action:0,point_count:1,index:0,id:0,getX:202.0,getY:417.0
06-18 23:55:35.622: V/test(10138): ---------------------------------------
06-18 23:55:35.622: V/test(10138): action:2,point_count:1,index:0,id:0,getX:209.0,getY:418.0
06-18 23:55:35.652: V/test(10138): ---------------------------------------
06-18 23:55:35.652: V/test(10138): action:2,point_count:1,index:0,id:0,getX:212.0,getY:419.0
06-18 23:55:35.662: V/test(10138): ---------------------------------------
06-18 23:55:35.662: V/test(10138): action:2,point_count:1,index:0,id:0,getX:214.0,getY:420.0
06-18 23:55:35.682: V/test(10138): ---------------------------------------
06-18 23:55:35.682: V/test(10138): action:2,point_count:1,index:0,id:0,getX:212.0,getY:419.0
06-18 23:55:35.742: V/test(10138): ---------------------------------------
06-18 23:55:35.742: V/test(10138): action:2,point_count:1,index:0,id:0,getX:215.0,getY:422.0
06-18 23:55:35.772: V/test(10138): ---------------------------------------
06-18 23:55:35.772: V/test(10138): action:2,point_count:1,index:0,id:0,getX:218.0,getY:426.0
06-18 23:55:35.792: V/test(10138): ---------------------------------------
06-18 23:55:35.792: V/test(10138): action:2,point_count:1,index:0,id:0,getX:221.0,getY:428.0
06-18 23:55:35.812: V/test(10138): ---------------------------------------
06-18 23:55:35.812: V/test(10138): action:2,point_count:1,index:0,id:0,getX:223.0,getY:430.0
06-18 23:55:35.832: V/test(10138): ---------------------------------------
06-18 23:55:35.832: V/test(10138): action:2,point_count:1,index:0,id:0,getX:225.0,getY:433.0
06-18 23:55:35.842: V/test(10138): ---------------------------------------
06-18 23:55:35.842: V/test(10138): action:2,point_count:1,index:0,id:0,getX:226.0,getY:435.0
06-18 23:55:35.862: V/test(10138): ---------------------------------------
06-18 23:55:35.862: V/test(10138): action:2,point_count:1,index:0,id:0,getX:227.0,getY:436.0
06-18 23:55:35.882: V/test(10138): ---------------------------------------
06-18 23:55:35.882: V/test(10138): action:2,point_count:1,index:0,id:0,getX:228.0,getY:438.0
06-18 23:55:35.902: V/test(10138): ---------------------------------------
06-18 23:55:35.902: V/test(10138): action:2,point_count:1,index:0,id:0,getX:228.0,getY:439.0
06-18 23:55:35.942: V/test(10138): ---------------------------------------
06-18 23:55:35.942: V/test(10138): action:2,point_count:1,index:0,id:0,getX:227.0,getY:440.0
06-18 23:55:35.972: V/test(10138): ---------------------------------------
06-18 23:55:35.972: V/test(10138): action:2,point_count:1,index:0,id:0,getX:227.0,getY:441.0
06-18 23:55:36.002: V/test(10138): ---------------------------------------
06-18 23:55:36.002: V/test(10138): action:2,point_count:1,index:0,id:0,getX:226.0,getY:441.0
06-18 23:55:36.032: V/test(10138): ---------------------------------------
06-18 23:55:36.032: V/test(10138): action:2,point_count:1,index:0,id:0,getX:227.0,getY:442.0
06-18 23:55:36.072: V/test(10138): ---------------------------------------
06-18 23:55:36.072: V/test(10138): action:2,point_count:1,index:0,id:0,getX:228.0,getY:443.0
06-18 23:55:36.072: V/test(10138): ---------------------------------------
06-18 23:55:36.072: V/test(10138): action:261,point_count:2,index:0,id:0,getX:228.0,getY:443.0,index:1,id:1,getX:388.0,getY:218.0
06-18 23:55:36.092: V/test(10138): ---------------------------------------
06-18 23:55:36.092: V/test(10138): action:2,point_count:2,index:0,id:0,getX:228.0,getY:444.0,index:1,id:1,getX:391.0,getY:222.0
06-18 23:55:36.112: V/test(10138): ---------------------------------------
06-18 23:55:36.112: V/test(10138): action:2,point_count:2,index:0,id:0,getX:228.0,getY:445.0,index:1,id:1,getX:391.0,getY:227.0
06-18 23:55:36.122: V/test(10138): ---------------------------------------
06-18 23:55:36.122: V/test(10138): action:2,point_count:2,index:0,id:0,getX:228.0,getY:447.0,index:1,id:1,getX:397.0,getY:235.0
06-18 23:55:36.142: V/test(10138): ---------------------------------------
06-18 23:55:36.142: V/test(10138): action:2,point_count:2,index:0,id:0,getX:228.0,getY:448.0,index:1,id:1,getX:402.0,getY:245.0
06-18 23:55:36.162: V/test(10138): ---------------------------------------
06-18 23:55:36.162: V/test(10138): action:2,point_count:2,index:0,id:0,getX:227.0,getY:449.0,index:1,id:1,getX:407.0,getY:257.0
06-18 23:55:36.182: V/test(10138): ---------------------------------------
06-18 23:55:36.182: V/test(10138): action:2,point_count:2,index:0,id:0,getX:227.0,getY:450.0,index:1,id:1,getX:414.0,getY:269.0
06-18 23:55:36.202: V/test(10138): ---------------------------------------
06-18 23:55:36.202: V/test(10138): action:2,point_count:2,index:0,id:0,getX:227.0,getY:452.0,index:1,id:1,getX:421.0,getY:279.0
06-18 23:55:36.212: V/test(10138): ---------------------------------------
06-18 23:55:36.212: V/test(10138): action:2,point_count:2,index:0,id:0,getX:227.0,getY:453.0,index:1,id:1,getX:428.0,getY:289.0
06-18 23:55:36.232: V/test(10138): ---------------------------------------
06-18 23:55:36.232: V/test(10138): action:2,point_count:2,index:0,id:0,getX:227.0,getY:455.0,index:1,id:1,getX:434.0,getY:296.0
06-18 23:55:36.252: V/test(10138): ---------------------------------------
06-18 23:55:36.252: V/test(10138): action:2,point_count:2,index:0,id:0,getX:226.0,getY:456.0,index:1,id:1,getX:440.0,getY:302.0
06-18 23:55:36.272: V/test(10138): ---------------------------------------
06-18 23:55:36.272: V/test(10138): action:2,point_count:2,index:0,id:0,getX:226.0,getY:457.0,index:1,id:1,getX:439.0,getY:308.0
06-18 23:55:36.292: V/test(10138): ---------------------------------------
06-18 23:55:36.292: V/test(10138): action:6,point_count:2,index:0,id:0,getX:226.0,getY:457.0,index:1,id:1,getX:439.0,getY:308.0
06-18 23:55:36.292: V/test(10138): ---------------------------------------
06-18 23:55:36.292: V/test(10138): action:1,point_count:1,index:0,id:1,getX:439.0,getY:308.0

紅色標註的部分,action261,是在第二根手指放上螢幕的時候,為什麼是261呢,看下261轉成16進位:0X00000105,這個action由2部分掩碼組成,指標索引0x00000001和操作的常量值ACTION_POINTER_DOWN(0x00000005),當第二根手指觸屏時是多點觸摸,所以動作是ACTION_POINTER_DOWN而不是ACTION_DOWN。

action:6,此時正是第一根手指離開螢幕,所以action掩碼是0x00000000|0x00000006(ACTION_POINTER_UP),再看下一組輸出, action:1,此時螢幕上只有一根手指了,並且離開螢幕,所以action是ACTION_UP。注意到index=0,id=1,和一開始的index=1,id=1不同了,index因為只剩一根手指所以變成了0,這說明了指標索引是不斷變化的。

另外,輸出曆史位置,並沒有得到想要的輸出,不知道有沒有解決過此問題的仁兄,求教

Log.v("test", event.getHistorySize()+"");for (int j = 0; j < event.getHistorySize(); j++) {for (int i = 0; i < points; i++) {result2.append(",index:").append(i).append(",id:"+ event.getPointerId(i));result2.append(",getHistoricalX:").append(event.getHistoricalX(i, j)).append(",getHistoricalY:").append(event.getHistoricalY(i, j));}}Log.v("test", "---------------------------------------");Log.v("test", result2.toString());

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.