上一章 我們學習了 android 簡單的觸摸屏操作 那這一章我們來看看 android 的手勢操作
android的手勢識别是android更人性化,讓我們的操作更簡單, 其實我們日常應用中不少地方都使用了手勢識别方法 比如 2011年那麼火的 憤怒的小鳥 中的 發射武器, uc 遊覽器 的左右滑動功能,這都是可以使用android的手勢識别來實作。
如果想要實作提高我們app 的使用者體驗,更具有可操作性,那這時android的GestureDetector 就派上用場了 , 我們先開看看GestureDetector這個類的api 給我們提供了哪些操作
下面是GestureDetector 這個類的概括情況
根據 <code>MotionEvent</code>事件檢測各種手勢. <code>GestureDetector.OnGestureListener</code> 回調函數用于通知使用者發生的手勢動作。該類僅處理 <code>MotionEvent</code> 事件中的觸摸事件(不處理軌迹球事件)。 使用該類的方法如下:
1:首先需要在初始化的時候建立GestureDetector對象執行個體
2:在View中的onTouchEvent方法中調用GestureDetector對象中的onTouchEvent方法當事件發生的時候就可以回調該方法
下面看看摘自android 的api 的摘要
interface
GestureDetector.OnDoubleTapListener
The listener that is used to notify when a double-tap or a confirmed single-tap occur.
GestureDetector.OnGestureListener
The listener that is used to notify when gestures occur.
class
GestureDetector.SimpleOnGestureListener
A convenience class to extend when you only want to listen for a subset of all the gestures.
現在我們來分析下GestureDetector這個類的概括情況
接口 OnDoubleTapListener 手勢監聽器 用于輕按兩下時發出通知
接口 OnGestureListener 手勢監聽器 用于發送手勢操作時發生通知 如 拖動,長按,按下,彈起 等手勢操作
類 SimpleOnGestureListener GestureDetector的擴充類 這個類的作用是當我們隻想使用部分手勢時, 而非全部的時候 就可以繼承這個類
GestureDetector 還有幾個公共方法 如下
boolean
isLongpressEnabled() 判定是否允許長點選
onTouchEvent(MotionEvent ev)
分析給定的動作事件,如果滿足條件,就觸發<code>GestureDetector.OnGestureListener</code> 中提供的回調函數。
void
setIsLongpressEnabled(boolean isLongpressEnabled)
設定是否允許長按。如果允許長按,當使用者按下并保持按下狀态時, 将收到一個長按事件,同時不再接收其它事件;如果禁用長按, 當使用者按下并保持按下狀态然後再移動手指時,将會接收到滾動事件。 長按預設為允許。
setOnDoubleTapListener(GestureDetector.OnDoubleTapListener onDoubleTapListener)
設定輕按兩下及其相關手勢的監聽器。
OnGestureListener 接口 的公共方法 如果你想在你的app view中實作下面這些手勢操作的話 繼承該接口 并實作下面這些方法即可
abstract boolean
onDown(MotionEvent e)
當輕觸手勢按下螢幕 時發生的事件.
onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
快速滑動後擡起事件的通知.
abstract void
onLongPress(MotionEvent e)
長按時的通知事件
onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
滑動螢幕時通知事件 為了友善提供了X軸和Y軸上的滾動距離.
onShowPress(MotionEvent e)
當使用者長點選後擡起時通知事件
onSingleTapUp(MotionEvent e)
當輕觸手勢擡起螢幕時發生的事件.
OnDoubleTapListener 接口的公共方法
onDoubleTap(MotionEvent e)
輕按兩下發生時的通知。
onDoubleTapEvent(MotionEvent e)
輕按兩下手勢過程中發生的事件,包括按下、移動和擡起事件。
onSingleTapConfirmed(MotionEvent e)
發生确定的單擊時執行。
與<code>onSingleTapUp(MotionEvent)</code>不同, 該事件在探測器确定使用者單擊後沒有發生導緻輕按兩下事件的第二次單擊時發生。
在實際應用中 我們根據我們所需要的功能實作不同的接口 或者 繼承自SimpleOnGestureListener 類 隻實作部分個人需要的方法 就可以了
我們這一章就以 OnGestureListener 接口來做示例 看看 他是怎麼使用的
直接看代碼 GameSurfaceView類
package yxqz.com;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.SurfaceHolder.Callback;
import android.widget.Toast;
/**
* android 手勢識别
* @author mahaile
*
*/
public class GameSurfaceView extends SurfaceView implements Callback,OnGestureListener{
private String TAG="GameView";
boolean flag; //線程标示位 當為false時停止重新整理界面
SurfaceHolder surfaceHolder;
GameViewThread gameViewThread;
float x=0,y=0;
int stat=0; //手勢識别狀态标示
private GestureDetector gd; // 手勢
Context context;
int width,height;
Bitmap bitmap_role;
public GameSurfaceView(Context context) {
super(context);
this.context=context;
surfaceHolder=this.getHolder();
surfaceHolder.addCallback(this); //添加回調
//設定焦點 如果不設定焦點的話 在該界面下 點選觸摸屏是無效的 預設為false
setFocusableInTouchMode(true);
bitmap_role=BitmapFactory.decodeResource(getResources(), R.drawable.role);
gd=new GestureDetector(this); //建立手勢監聽對象
}
public void onDraw(Canvas canvas){
canvas.drawColor(Color.BLACK);
//canvas.drawBitmap(bitmap_role, width/2-bitmap_role.getWidth()/2, y, null);
canvas.drawBitmap(bitmap_role, x-bitmap_role.getWidth()/2, y-bitmap_role.getHeight()/2, null);
//重寫父類中的 onTouchEvent就可以監聽到 觸摸事件了 記住要設定焦點喔
@Override
public boolean onTouchEvent(MotionEvent event) {
gd.onTouchEvent(event); //通知手勢識别方法
return true;
public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height) {
public void surfaceCreated(SurfaceHolder surfaceHolder) {
//擷取螢幕的 寬高 隻有在 surface建立的時候 才有效 ,才構造方法中擷取 寬高是擷取不到的
width=this.getWidth();
height=this.getHeight();
//初始化繪圖線程
gameViewThread=new GameViewThread();
gameViewThread.flag=true;
gameViewThread.start();
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
gameViewThread.flag=false; //銷毀線程
class GameViewThread extends Thread{
public boolean flag;
public void run(){
while(flag){
Canvas canvas=null;
try{
canvas=surfaceHolder.lockCanvas(); //鎖定畫布 并擷取canvas
onDraw(canvas);//調用onDraw 渲染到螢幕
surfaceHolder.unlockCanvasAndPost(canvas); //此步不要忘記了喔 否則界面上顯示不出來的
}catch(Exception e){
e.printStackTrace();
try {
Thread.sleep(10);//線程休眠時間 控制幀數
} catch (InterruptedException e) {
// TODO Auto-generated catch block
} //每一秒重新整理一次
//**************************下面是手勢識别的重寫方法*******************************************
//螢幕點下
public boolean onDown(MotionEvent arg0) {
Log.d(TAG, "onDown");
Toast.makeText(this.context, "你點選了螢幕", Toast.LENGTH_SHORT).show();
return false;
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
Log.d(TAG, "onFling");
Toast.makeText(this.context, "你拖動螢幕後彈起", Toast.LENGTH_SHORT).show();
//螢幕點下 并長按時觸發
public void onLongPress(MotionEvent e) {
Log.d(TAG, "onLongPress");
Toast.makeText(this.context, "你長按了螢幕", Toast.LENGTH_SHORT).show();
//螢幕拖動
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
this.x=this.x-distanceX;
this.y=this.y-distanceY;
Toast.makeText(this.context, "你拖動了螢幕", Toast.LENGTH_SHORT).show();
//螢幕長按
public void onShowPress(MotionEvent e) {
// TODO Auto-generated method stub
Toast.makeText(this.context, "你長按螢幕後彈起", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onShowPress");
//螢幕點選後彈起
public boolean onSingleTapUp(MotionEvent e) {
Log.d(TAG, "onSingleTapUp");
Toast.makeText(this.context, "你彈起螢幕", Toast.LENGTH_SHORT).show();
有一點大家需要注意一下 每次執行手勢時 可以會執行多個手勢通知 大家需要留意一下喔,避免重複操作app邏輯
上面的代碼中 紅色部分标示了 手勢識别的主要部分 大家趕快加到自己的app 裡面吧 讓自己的app 更有吸引力 其他兩種種方式 和這種很類似,各位童鞋可以自己試試喔
在後續的過程中 我們會有一章 遊戲地圖 介紹 的章節 , 那時我們使用手勢識别來拖動地圖
歡迎各位童鞋 來拍磚喔,,有啥不懂的地方留言給我喔 一起學習 共同進步 加油 。。
下面是源碼位址
http://download.csdn.net/detail/ma_haile/4221223