我們在觸控事件中可以得到motionevent物件,
先介紹motionevent的幾個常用方法:
getpointercount()這個方法可以獲取觸控點個數,一般來說處理兩個點就行了,3點的情況實在太少getactionmasked()
這個方法用於獲取觸控事件的觸控狀態,我們平時使用的getaction()方法是無法捕獲多點觸控的情況的,使用getactionmasked()就額外可以捕獲到action_pointer_down和action_pointer_up事件
motionevent.action_pointer_down:當螢幕上已經有乙個點被按住,此時再按下其他點時觸發。
motionevent.action_pointer_up:
當螢幕上有多個點被按住,鬆開其中乙個點時觸發(即非最後乙個點被放開時)。
對觸點進行分類處理是多點觸控的核心思想,這裡提供了3個方法幫助我們獲取我們想要的觸點:為了更好地理解多點觸控原理,我們來做乙個例子:自定義乙個view可以雙手連續拖拽,鬆開後彈回到原位我們得到的motionevent物件維護了乙個有序的觸點序列,這個序列記錄了當前螢幕中的所有觸點,我們可以通過index下標獲取指定觸點的資訊,比如motionevent.getx()可以獲取觸控點的x座標,它還提供了乙個》 過載方法motionevent.getx(index),獲取指定觸點的x座標。//獲取當前觸點的index下標
getactionindex()
//獲取觸點唯一id
getpointerid()
//通過觸點的id獲取index下標
findpointerindex()
而這個有序序列的位置並不是不變的,根據使用者觸控的順序,序列的順序是不斷變化的,也就是說你使用乙個下標在同乙個觸控事件中兩次獲取到的不一定是同乙個觸點,為了解決這個問題系統為每個觸點關聯了唯一的id,而這個id是固定不變的,我們獲取指定觸點的思路就變成了 :1.使用id獲取index,2.再用index獲取觸點資訊
如下通過乙個id獲取指定觸點的xy座標:
上面的**還可以寫成://motionevent ev
int pointerindex = ev.findpointerindex(ev, mactivepointerid);
float x = ev.getx(pointerindex);
float y = ev.gety(pointerindex);
motioneventcompat是v4中引入的乙個相容低版本(api 8)的類,用於相容低版本的motionevent,使用方法一》 致,後面的介紹都統一使用motioneventcompat//motionevent ev
int pointerindex = motioneventcompat.findpointerindex(ev, mactivepointerid);
float x = motioneventcompat.getx(ev, pointerindex);
float y = motioneventcompat.gety(ev, pointerindex);
效果圖:(注意這是兩隻手連續拖拽)
首先建立乙個testview繼承自view:
public
class
testview
extends
view
}
重寫dispatchtouchevent,在裡面呼叫乙個用於處理多點觸控的自定義方法dealmultouchevent
@override
public boolean dispatchtouchevent(motionevent event)
使用getactionmasked獲取觸控事件進行分類處理:
public
void
dealmultouchevent(motionevent ev)
}
首先,在action_down的時候(第一隻手按下),我們獲取觸點的x,y座標,儲存在mlastx和mlasty中,並獲取當前觸點id,記作活動點,儲存在乙個類變數中:
case motionevent.action_down:
case motionevent.action_move:
當使用者另乙隻手再次按下時(觸發第二個觸點),觸發action_pointer_down事件,如果觸發的點不是活動點的話,就更新mlastx 、mlasty,並設其為活動點:
case motionevent.action_pointer_down:
break;
}
當使用者兩隻手都在觸控事件中,這時鬆開其中一種手(不管是不是活動點的那乙隻手),觸發action_pointer_up事件,判斷,如果鬆開的手是活動點的那乙隻手,就更新mlastx 、mlasty,並把另一觸點設為活動點:
case motionevent.action_pointer_up:
break;
}
當使用者鬆開另乙隻手時(此時只有乙隻手再觸控),觸發action_up,我們清理活動點,設定為「無」
action_cancel 也一同處理
case motionevent.action_up:
case motionevent.action_cancel:
mactivepointerid = motionevent.invalid_pointer_id;
break
;
以上就是多點觸控的核心**了。
總結一下思路:
在action_down中設定初始的活動點和位置資訊,在多點按下和多點鬆開的事件action_pointer_down、action_pointer_up中根據使用者按下和鬆開的情況,更新活動點和位置資訊,始終保證最後按下和最後鬆開的點為活動點,在action_move中始終獲取活動點的位置資訊來計算拖拽距離,最後在action_up和action_cancel中清除活動點。
剩下的就是拖拽和復位的功能:
重新ontouchevent,在action_move中進行拖拽,在action_up和action_cancel進行復位:
@override
public
boolean
ontouchevent(motionevent ev)
return
true;
}
最後給出拖拽和復位的方法,拖拽是通過layout方法來進行位移,復位則是利用位移動畫來完成,沒什麼難點,不作介紹了。
//拖拽方法
private
void
domove()
int movedx = (int) (dx/2);
int movedy = (int) (dy/2);
if (movedy!=0)
}//復位方法
private
void
resetposition()
android 多點觸控
下面是一些常用的函式解釋 copy過來滴.event.getaction 獲取觸控動作比如action down event.getpointercount 獲取觸控點的數量,比如2則可能是兩個手指同時按壓螢幕 event.getpointerid nid 對於每個觸控的點的細節,我們可以通過乙個迴...
android中多點觸控開發紀要
筆者在專案開發中,碰到過針對螢幕的五指觸控測試需求,實現方式為可以自定義個view,然後在ontouchevent 方法中對motionevent進行處理,核心 如下,要注意的地方在注釋中已做說明。override public boolean ontouchevent motionevent ev...
關於android多點觸控
最近專案需要乙個多點觸控縮放的功能。然後上網查了下資料 總結一下 首先android sdk版本很重要,比如你在androidmanifest.xml中指定android minsdkversion 4 並且建工程的時候選的是android 2.2就表示你的應用相容android1.6 androi...