關於android多點觸控
原文:https://www.cnblogs.com/tianjian/archive/2011/12/01/2270657.html
最近項目需要一個多點觸控縮放的功能。然後上網查了下資料 總結一下:
首先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就暫不考慮了。
接下來看代碼:
package laahaa.framework; import android.content.Context; import android.graphics.PointF; import android.util.AttributeSet; import android.util.FloatMath; import android.view.MotionEvent; import android.view.SurfaceHolder; /** * * 遊戲畫布 */ public class GameView2X extends GameView implements SurfaceHolder.Callback { private float oldDist; private PointF midPoint = new PointF(); private boolean isZoom = false; public GameView2X(Context context, AttributeSet attrs) { super(context, attrs); } public boolean onTouchEvent(MotionEvent event) { switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: super.actionDown(event); break; case MotionEvent.ACTION_POINTER_UP: isZoom = false; break; /** * API原文是 A non-primary pointer has gone down. * 翻譯過來就是:非第一個點按下 */ case MotionEvent.ACTION_POINTER_DOWN: oldDist = spacing(event); midPoint(midPoint, event); isZoom = true; break; case MotionEvent.ACTION_MOVE: if (isZoom) { float newDist = spacing(event); /** * 表示新的距離比兩個手指剛觸碰的距離大 * ( +10個像素用來延遲一下放大,不然稍微動一點像素,也放大,感覺也太快了。) */ if (newDist + 10 > oldDist) { super.getGameThread().getGameDraw() .checkXY((int) midPoint.x, (int) midPoint.y); super.getGameThread().getGameDraw().setIsZoom(true); } /** * 表示新的距離比兩個手指剛觸碰的距離小 */ if (newDist + 10 < oldDist) { super.getGameThread().getGameDraw().setIsZoom(false); GameDraw.newX = 0; GameDraw.newY = 0; } } super.actionMove(event); break; } return true; } private float spacing(MotionEvent event) { float x = event.getX(0) - event.getX(1); float y = event.getY(0) - event.getY(1); return FloatMath.sqrt(x * x + y * y); } private void midPoint(PointF point, MotionEvent event) { float x = event.getX(0) + event.getX(1); float y = event.getY(0) + event.getY(1); point.set(x / 2, y / 2); } }
這裏要注意下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,而在兩個觸電的時候,該方法則根據兩點相對位置變化而返回不同的值
最後更新:2017-04-02 06:52:15