1. 程式人生 > >Android中Gesture手勢的基本用法(總結)

Android中Gesture手勢的基本用法(總結)

應用場景:

(1)左右上下滑動螢幕的事件監聽。比如,上拉彈出自定義的底部佈局之類的,換頁之類的等等。

(2)畫一些不規則的幾何圖形。

執行順序:

  • 1.手指觸碰螢幕時,觸發MotionEvent事件!
  • 2.該事件被OnTouchListener監聽,可在它的onTouch()方法中獲得該MotionEvent物件!
  • 3.通過GestureDetector轉發MotionEvent物件給OnGestureListener
  • 4.我們可以通過OnGestureListener獲得該物件,然後獲取相關資訊,以及做相關處理!

我們來看下上述的三個類都是幹嘛的: MotionEvent: 這個類用於封裝手勢、觸控筆、軌跡球等等的動作事件。 其內部封裝了兩個重要的屬性X和Y,這兩個屬性分別用於記錄橫軸和縱軸的座標。 GestureDetector

: 識別各種手勢。 OnGestureListener: 這是一個手勢互動的監聽介面,其中提供了多個抽象方法, 並根據GestureDetector的手勢識別結果呼叫相對應的方法。

功能程式碼:

package com.deepreality.summarizetestdemo;

import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.widget.Toast;

public class GestureActivity extends AppCompatActivity {

    private Context mContext;
    private static String TAG = "GestureListener---";

    private MyGestureListener myGestureListener;
    private GestureDetector gestureDetector;

    private static int MIN_MOVE = 200;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_gesture);

        baseDataInit();
        bindViews();
        viewsAddListener();

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    private void baseDataInit() {
        mContext = this;
        myGestureListener = new MyGestureListener();
        gestureDetector = new GestureDetector(mContext, myGestureListener);
    }

    private void bindViews() {

    }

    private void viewsAddListener() {

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return gestureDetector.onTouchEvent(event);
    }

    class MyGestureListener implements GestureDetector.OnGestureListener {

        @Override
        public boolean onDown(MotionEvent e) {
            Log.e(TAG, "onDown:按下");
            return false;
        }

        @Override
        public void onShowPress(MotionEvent e) {
            Log.e(TAG, "onShowPress:手指按下一段時間,但是還沒到長按");
        }

        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            Log.e(TAG, "onSingleTapUp:手指離開螢幕的一瞬間");
            return false;
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            Log.e(TAG, "onScroll:在螢幕上滑動");
            return false;
        }

        @Override
        public void onLongPress(MotionEvent e) {
            Log.e(TAG, "onLongPress:手指長按螢幕");
        }

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
            Log.e(TAG, "onFling:迅速滑動並鬆開");
            if (e1.getY() - e2.getY() > MIN_MOVE) {
                Toast.makeText(mContext, "上拉操作", Toast.LENGTH_SHORT).show();
            } else if (e1.getY() - e2.getY() < MIN_MOVE) {
                Toast.makeText(mContext, "下拉操作", Toast.LENGTH_SHORT).show();
            }
            Log.e("e1-Y", e1.getY() + "");
            Log.e("e2-Y", e2.getY() + "");
            return true;
        }
    }
}

特別注意:

這裡用到的是OnGestureListener,需要實現該介面的所有方法,我這邊如果僅僅使用滑動操作,顯然不太合理。那麼怎麼處理呢?使用SimpleOnGestureListener即可,需要哪個,就實現哪個方法。

附加:

如何在螢幕畫一些不規則圖形?比如,銀行常用的電子簽名功能。

這裡用到的是:GestureOverlayView(手勢編輯元件)

如何使用呢?

(1)佈局檔案:

<android.gesture.GestureOverlayView
    android:id="@+id/GestureComponent_GOVGesture"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    android:gestureColor="@color/colorBlack"
    android:gestureStrokeType="multiple"></android.gesture.GestureOverlayView>

(2)獲取元件並進行相關設定:

//設定手勢編輯元件
//手勢的顏色
GOVGesture.setGestureColor(getResources().getColor(R.color.colorBlack));
//手勢的粗細
GOVGesture.setGestureStrokeWidth(5);
/*手勢繪製完成後淡出螢幕的時間間隔,即繪製完手指離開屏幕後相隔多長時間手勢從螢幕上消失;
 * 可以理解為手勢繪製完成手指離開屏幕後到呼叫onGesturePerformed的時間間隔
 * 預設值為420毫秒,這裡設定為2秒
 */
GOVGesture.setFadeOffset(2000);

(3)新增手勢編輯完成監聽事件

GOVGesture.addOnGesturePerformedListener(this);

(4)通過手勢物件獲取ImageView所需的Bitmap物件。

//給ImageView賦值手勢
bitmap = gesture.toBitmap(100, 100, 10, getResources().getColor(R.color.colorBlack));
ivGesture.setImageBitmap(bitmap);

如何儲存和比對手勢呢?

(1)儲存手勢

//檔案對應的手勢庫(儲存)
GestureLibrary gestureLib = GestureLibraries.fromFile("/mnt/sdcard/mygestures");
gestureLib.addGesture(etName.getText().toString(), gesture);
gestureLib.save();

(2)比對手勢

第一步:

//載入本地手勢庫
GestureLibrary gestureLibrary = GestureLibraries.fromFile("mmt/sdcard/mygestures");
if (gestureLibrary.load()) {
    Toast.makeText(mContext, "手勢庫載入成功", Toast.LENGTH_SHORT).show();
} else {
    Toast.makeText(mContext, "手勢庫載入失敗", Toast.LENGTH_SHORT).show();
}

第二步:

在GesturePerformedListener介面方法OnGesturePerformed裡進行識別操作:

//識別使用者剛繪製的手勢
ArrayList<Prediction> predictions = gestureLibrary.recognize(gesture);
ArrayList<String> result = new ArrayList<String>();
//遍歷所有找到的Prediction物件
for (Prediction prediction : predictions) {
    if (prediction.score > 2.0) {
        result.add("與手勢【" + prediction.name + "】相似度為" + prediction.score);
    }
}
if (result.size() > 0) {
    ArrayAdapter<Object> adapter = new ArrayAdapter<Object>(mContext,
            android.R.layout.simple_dropdown_item_1line, result.toArray());
    new AlertDialog.Builder(mContext).setAdapter(adapter, null).setPositiveButton("確定", null).show();
}else{
    Toast.makeText(mContext,"無法找到匹配的手勢!", Toast.LENGTH_SHORT).show();
}

對了,不要忘記新增使用者許可權哦!