1. 程式人生 > >Android開發-手勢識別

Android開發-手勢識別

使用OnTouchListener進行手勢識別

下面是例項程式碼

ImageView img;
        //對ImageView繫結觸控監聽
        img.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                switch (motionEvent.getAction())
                {
                    case MotionEvent.ACTION_DOWN:
                        Toast.makeText(OnTouchActivity.this, "按下", Toast.LENGTH_SHORT).show();
                        break;
                    case MotionEvent.ACTION_UP:
                        Toast.makeText(OnTouchActivity.this, "擡起", Toast.LENGTH_SHORT).show();
                        break;
                }
                return true;
            }
        });

通過引數motionEvent可以獲得當前的活動(motionEvent.getAction()方法)

檢視MotionEvent類,可以發現其中判斷動作的常量

如:

public static final int ACTION_DOWN = 0;按下

public static final int ACTION_UP = 1;擡起

public static final int ACTION_MOVE = 2;移動

public static final int ACTION_CANCEL = 3;取消

...

將當前活動與MotionEvent類中的常量進行比較,便可以知道當前的觸控方式了

除了使用getAction方法來判斷當前活動的觸控方式外,還可以通過其他方法來實現更多的手勢識別

例如使用getX()方法或getY()方法來獲取座標,並實現識別手指向左向右向上向下滑動的識別功能

示例如下:

img.setOnTouchListener(new View.OnTouchListener() {
            float X1 = 0;
            float X2 = 0;
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                if (motionEvent.getAction()==MotionEvent.ACTION_DOWN)
                {
                    X1 = motionEvent.getX();
                }
                else if (motionEvent.getAction()==MotionEvent.ACTION_UP)
                {
                    X2 = motionEvent.getX();
                    if (X1 - X2 > 60)
                    {
                        Toast.makeText(getApplicationContext(), "正在向左滑動", Toast.LENGTH_SHORT).show();
                    }
                    else if (X1 - X2 < -60)
                    {
                        Toast.makeText(getApplicationContext(), "正在向右滑動", Toast.LENGTH_SHORT).show();
                    }
                }
                return true;
            }
        });

相對而言,直接使用OnTouch來識別手勢比較簡單,但如果用來處理一些相對複雜的手勢時就比較麻煩了

使用OnGestureListener進行手勢識別

使用這個類能夠識別我們更多的手勢,GestureDetector.OnGestureListener介面中帶有這麼幾個方法


    @Override
    public boolean onDown(MotionEvent motionEvent) {
        return true;
        //按下時呼叫
    }

    @Override
    public void onShowPress(MotionEvent motionEvent) {
        //按下後未移動未鬆開時呼叫
    }

    @Override
    public boolean onSingleTapUp(MotionEvent motionEvent) {
        return true;
        //按下後擡起時呼叫
    }

    @Override
    public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
        return true;
        //滾動時呼叫,滑鼠滾輪滾動也能觸發
    }

    @Override
    public void onLongPress(MotionEvent motionEvent) {
        //長按時呼叫
    }

    @Override
    public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
        return true;
        //滑動時呼叫
    }

其中

onScroll滾動方法,由一個MotionEvent.ACTION_DOWN以及多個MotionEvent.ACTION_MOVE觸發

onFling滑動方法由兩個MotionEvent觸發,引數解釋如下:

MotionEvent motionEvent :第一個按下的觸控,即滑動時手指第一次按下時觸發

MotionEvent motionEvent1:第二個MotionEvent引數,為手指滑動後擡起時觸發,即滑動完成擡起手指時

float v:X軸上的移動速度,畫素/秒

float v1:Y軸上的移動速度,畫素/秒

下面是使用OnGestureListener手勢識別的例項

一:定義一個類實現OnGestureListener介面,並重寫其中的方法

public class MyOnTouch implements GestureDetector.OnGestureListener{

    Context context;
    public MyOnTouch(Context context){
        this.context = context;
    }

    @Override
    public boolean onDown(MotionEvent motionEvent) {
        Toast.makeText(context, "onDown", Toast.LENGTH_SHORT).show();
        return true;
        //按下時呼叫
    }

    @Override
    public void onShowPress(MotionEvent motionEvent) {
        Toast.makeText(context, "onShowPress", Toast.LENGTH_SHORT).show();
        //按下後未移動未鬆開時呼叫
    }

    @Override
    public boolean onSingleTapUp(MotionEvent motionEvent) {
        Toast.makeText(context, "onSingleTapUp", Toast.LENGTH_SHORT).show();
        return true;
        //按下後擡起時呼叫
    }

    @Override
    public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
        Toast.makeText(context, "onScroll", Toast.LENGTH_SHORT).show();
        return true;
        //滾動時呼叫,滑鼠滾輪滾動也能觸發
    }

    @Override
    public void onLongPress(MotionEvent motionEvent) {
        //長按時呼叫
    }

    @Override
    public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
        Toast.makeText(context, "onFling", Toast.LENGTH_SHORT).show();
        return true;
        //滑動時呼叫
    }
}

二:定義一個GestureDetectorCompat物件並傳入引數(應用上下文、以及一個OnGestureListener介面,這裡傳入我們重寫過的類)下面是完整的程式碼

public class OnTouchActivity extends Activity{

    //定義一個GestureDetectorCompat物件
    GestureDetectorCompat gestureDetectorCompat;
    ImageView img;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_on_touch);
        setListener();
    }

    public void setListener()
    {
        //為ImageView繫結觸控監聽器
        img.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                //返回的事件處理為gestureDetectorCompat的事件處理
                return gestureDetectorCompat.onTouchEvent(motionEvent);
            }
        });
    }
}

*在觸發觸控方法時,如果想要觸控方法繼續判斷執行,需要在執行的方法中return結果true,否則將不再執行