關於android多點觸控

來源:互聯網
上載者:User

最近項目需要一個多點觸控縮放的功能。然後上網查了下資料 總結一下:

首先android sdk版本很重要,比如你在AndroidManifest.xml中指定android:minSdkVersion="4"  並且建工程的時候選的是android 2.2就表示你的應用相容android1.6~android2.2

之間的版本。但是多點觸控的API在1.6~~2,1~~,2,2~~三個版本中都是不一樣的。比如android2.2中onTouchEvent(MotionEvent event) 這裡可以用event.getActionMasked()

表示用於多點觸控檢測點。但在1.6和2.1中並沒有event.getActionMasked()這個方法,查源碼後發現其實他就是吧event.getAction()& MotionEvent.ACTION_MASK封裝了一下。

對於這些小細節我們要特別注意,因為這關乎版本相容問題,也許你在2.2的裝置上運行沒什麼問題,但1.6或者2.1就會出個什麼問題之類的。所以對於1.6以後新增加的功能,要特別注意API

的使用。1.5就暫不考慮了。

接下來看代碼:

 1 package laahaa.framework;
2
3
4
5 import android.content.Context;
6 import android.graphics.PointF;
7 import android.util.AttributeSet;
8 import android.util.FloatMath;
9 import android.view.MotionEvent;
10 import android.view.SurfaceHolder;
11
12 /**
13 *
14 * 遊戲畫布
15 */
16 public class GameView2X extends GameView implements SurfaceHolder.Callback {
17
18 private float oldDist;
19 private PointF midPoint = new PointF();
20 private boolean isZoom = false;
21
22 public GameView2X(Context context, AttributeSet attrs) {
23 super(context, attrs);
24
25 }
26
27 public boolean onTouchEvent(MotionEvent event) {
28
29 switch (event.getAction() & MotionEvent.ACTION_MASK) {
30 case MotionEvent.ACTION_DOWN:
31 super.actionDown(event);
32 break;
33 case MotionEvent.ACTION_POINTER_UP:
34 isZoom = false;
35 break;
36 /**
37 * API原文是 A non-primary pointer has gone down.
38 * 翻譯過來就是:非第一個點按下
39 */
40 case MotionEvent.ACTION_POINTER_DOWN:
41 oldDist = spacing(event);
42 midPoint(midPoint, event);
43 isZoom = true;
44 break;
45 case MotionEvent.ACTION_MOVE:
46 if (isZoom) {
47 float newDist = spacing(event);
48 /**
49 * 表示新的距離比兩個手指剛觸碰的距離大
50 * ( +10個像素用來延遲一下放大,不然稍微動一點像素,也放大,感覺也太快了。)
51 */
52 if (newDist + 10 > oldDist) {
53 super.getGameThread().getGameDraw()
54 .checkXY((int) midPoint.x, (int) midPoint.y);
55 super.getGameThread().getGameDraw().setIsZoom(true);
56 }
57 /**
58 * 表示新的距離比兩個手指剛觸碰的距離小
59 */
60 if (newDist + 10 < oldDist) {
61 super.getGameThread().getGameDraw().setIsZoom(false);
62 GameDraw.newX = 0;
63 GameDraw.newY = 0;
64 }
65 }
66 super.actionMove(event);
67
68 break;
69 }
70
71 return true;
72 }
73
74 private float spacing(MotionEvent event) {
75 float x = event.getX(0) - event.getX(1);
76 float y = event.getY(0) - event.getY(1);
77 return FloatMath.sqrt(x * x + y * y);
78 }
79
80 private void midPoint(PointF point, MotionEvent event) {
81 float x = event.getX(0) + event.getX(1);
82 float y = event.getY(0) + event.getY(1);
83 point.set(x / 2, y / 2);
84 }
85 }

這裡要注意下GameView2X表示2.0以上的版本 他繼承於我自己寫的低版本的GameView。因為有很多重複代碼繼承是必須的。最後要注意下:擷取當前應用的SDK版本代碼為:

int sdkVersion=Integer.parseInt(Build.VERSION.SDK);

你需要在最開始初始化的時候運行它,寫入GameConfig中比較好,後面單例調用就好了。或者不喜歡單例的直接static final 也行。然後再選擇gameview的時候 加個if判斷,

if(sdkVersion<Build.VERSION_CODES.ECLAIR)

{}

else

{}

好了,這裡的多點觸控放大比較簡單,其實可以根據前距離/後距離的比值來動態設定縮放。這隻是個簡單的例子。

ps:最近發現 onTouchEvent事件中的參數MotionEvent,它有一個getSize()方法。在一個點的時候,該方法永遠返回0,而在兩個觸電的時候,該方法則根據兩點相對位置變化而返回不同的值 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.