Android多點觸摸互動處理,放大縮小圖片
多點觸摸(MultiTouch),指的是允許電腦使用者同時通過多個手指來控製圖形介面的一種技術。與多點觸摸技術相對應的就是單點觸摸,單點觸摸的裝置已經有很多年了,小尺寸的有觸摸式的手機,大尺寸的最常見的就是銀行裡的ATM機和排隊查詢機等等。 多點觸摸技術在實際開發過程中,用的最多的就是放大縮小功能。比如有一些圖片瀏覽器,就可以用多個手指在螢幕上操作,對圖片進行放大或者縮小。再比如一些瀏覽器,也可以通過多點觸摸放大或者縮小字型。其實放大縮小也只是多點觸摸的實際應用範例之一,有了多點觸摸技術,在一定程度上就可以創新出更多的操作方式來,實現更酷的人機互動。 理論上,Android系統本身可以處理多達256個手指的觸摸,這主要取決於手機硬體的支援。當然,支援多點觸摸的手機,也不會支援這麼多點,一般是支援2個點或者4個點。對於開發人員來說,編寫多點觸摸的代碼與編寫單點觸摸的代碼,並沒有很大的差異。這是因為,Android SDK中的MotionEvent類不僅封裝了單點觸摸的訊息,也封裝了多點觸摸的訊息,對於單點觸摸和多點觸摸的處理方式幾乎是一樣的。 在處理單點觸摸中,我們一般會用到MotionEvent.ACTION_DOWN、ACTION_UP、ACTION_MOVE,然後可以用一個Switch語句來分別進行處理。ACTION_DOWN和ACTION_UP就是單點觸控螢幕幕,按下去和放開的操作,ACTION_MOVE就是手指在螢幕上移動的操作。 在處理多點觸摸的過程中,我們還需要用到MotionEvent.ACTION_MASK。一般使用switch(event.getAction() & MotionEvent.ACTION_MASK)就可以處理處理多點觸摸的ACTION_POINTER_DOWN和ACTION_POINTER_UP事件。代碼調用這個“與”操作以後,當第二個手指按下或者放開,就會觸發ACTION_POINTER_DOWN或者ACTION_POINTER_UP事件。 下面我們以一個實際的例子來說明如何在代碼中實現多點觸摸功能。在這裡我們載入一個圖片,載入圖片後,可以通過一個手指對圖片進行拖動,也可以通過兩個手指的滑動實現圖片的放大縮小功能。
java
private float currentDistance=0; private float lastDistance=-1; private FrameLayout frame; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); frame= (FrameLayout) findViewById(R.id.frame); final ImageView img= (ImageView) findViewById(R.id.img); frame.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()){ case MotionEvent.ACTION_DOWN: //觸摸按下 Log.i("MotionEvent","ACTION_DOWN"); break; } switch (event.getAction()){ case MotionEvent.ACTION_MOVE: //觸摸移動 Log.i("MotionEvent","ACTION_MOVE"); FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) img.getLayoutParams(); if(event.getPointerCount()==1) { //單個觸摸點,並拖動圖片 System.out.println(String.format("X:%f,Y:%f", event.getX(), event.getY())); layoutParams.leftMargin = (int) event.getX()-10; layoutParams.topMargin = (int) event.getY()-10; img.setLayoutParams(layoutParams); } System.out.println("pointer count 觸摸點個數"+event.getPointerCount());//觸摸點個數 //多個觸摸點的座標 //手勢放大縮小圖片 if (event.getPointerCount()>=2){ System.out.println(String.format("多個觸摸點的座標X1:%f;Y1:%f", event.getX(0), event.getX(0))); float offsetX=event.getX(0)-event.getX(1); float offsetY=event.getY(0)-event.getY(1); currentDistance=(float)Math.sqrt(offsetX*offsetX+offsetY*offsetY); if(lastDistance<0){ lastDistance=currentDistance; }else { if(currentDistance-lastDistance>5){ //5px;有誤差 FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) img.getLayoutParams(); System.out.println("放大"); lp.width= (int) (1.1f*img.getWidth()); lp.height=(int) (1.1f*img.getHeight()); img.setLayoutParams(lp); lastDistance=currentDistance; //放大 }else if (lastDistance-currentDistance>5){ lastDistance=currentDistance; //縮小 FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) img.getLayoutParams(); lp.width= (int) (0.9f*img.getWidth()); lp.height=(int) (0.9f*img.getHeight()); img.setLayoutParams(lp); } } } break; } switch (event.getAction()){ case MotionEvent.ACTION_UP: //觸摸彈起 Log.i("MotionEvent","ACTION_UP"); break; } return true;//true:需要催發後續事件;false:不需要鬚髮後續事件(只能執行一次) } }); }注意:
private float currentDistance=0; private float lastDistance=-1;