觸控手勢

您可以透過 Android SDK 從 Glass 觸控板存取原始資料。

不過,GDK 提供的手勢手勢偵測工具可以自動偵測 Glass 上的常用手勢,包括輕觸、滑動和捲動等。

此外,根據預設,系統會將簡易手勢轉譯為 D-pad 事件,讓你不用使用手勢偵測工具也能輕鬆處理。

將手勢偵測為 D-pad 按鍵事件

根據預設,Glass 系統會將簡單的手勢轉換成 D-pad 重要事件。這可讓您監聽活動或檢視畫面的 onKeyDown()onKeyUp() 事件,以便將下列手勢當做 D-pad 索引鍵處理:

下列程式碼片段會偵測使用者輕觸觸控板的時機:

public class MyActivity extends Activity {
    ...
    @Override
    public boolean onKeyDown(int keycode, KeyEvent event) {
        if (keycode == KeyEvent.KEYCODE_DPAD_CENTER) {
            // user tapped touchpad, do something
            return true;
        }
        ...
        return super.onKeyDown(keycode, event);
    }
}

如要偵測個別檢視畫面的輕觸方式,是為檢視畫面實作 OnClickListener。當使用者輕觸焦點 (輕觸為 D-Pad 中心按鈕) 的觸控板時,檢視畫面可使用 OnClickListener 處理事件。

public final class MyActivity extends Activity implements OnClickListener {

    View cardView;

    @Override
    protected void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        cardView = new Card(this).setText("Tap to carry out an action").getView();
        // To receive touch events from the touchpad, the view should be focusable.
        cardView.setOnClickListener(this);
        cardView.setFocusable(true);
        cardView.setFocusableInTouchMode(true);
        setContentView(cardView);
    }

    @Override
    protected void onResume() {
        // To receive touch events from the touchpad, the view should have focus.
        cardView.requestFocus();
        super.onResume();
    }

    @Override
    public void onClick(View v) {
        // perform desired action
    }
}

使用手勢偵測工具偵測手勢

手勢偵測器可讓您偵測簡單的手勢和更複雜的手勢,例如使用多個手指或捲動的手勢。複雜手勢沒有對應的 D-pad 金鑰。

GestureDetector 提供事件監聽器介面,您可以導入這個介面以接收手勢的通知。

偵測活動層級手勢

當您不在使用者介面的哪個部分有焦點時,適合在活動層級偵測手勢。舉例來說,如果您想在使用者輕觸觸控板時開啟選單,無論聚焦的檢視畫面為何,您都必須在活動中處理 MotionEvent

以下範例會執行下列操作:

  1. 建立 GestureDetector 來實作事件監聽器來處理已識別的手勢。
  2. 覆寫活動的 onGenericMotionEvent() 方法,將動作事件傳送至手勢偵測工具 onMotionEvent() 方法。

當動作事件發生時,系統會將該事件傳送至手勢偵測工具。如果偵測到,手勢偵測器會通知適當的事件監聽器來處理事件。

public class MainActivity extends Activity {
    private GestureDetector mGestureDetector;
    // ...
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // ...
        mGestureDetector = createGestureDetector(this);
    }

    private GestureDetector createGestureDetector(Context context) {
    GestureDetector gestureDetector = new GestureDetector(context);
        //Create a base listener for generic gestures
        gestureDetector.setBaseListener( new GestureDetector.BaseListener() {
            @Override
            public boolean onGesture(Gesture gesture) {
                if (gesture == Gesture.TAP) {
                    // do something on tap
                    return true;
                } else if (gesture == Gesture.TWO_TAP) {
                    // do something on two finger tap
                    return true;
                } else if (gesture == Gesture.SWIPE_RIGHT) {
                    // do something on right (forward) swipe
                    return true;
                } else if (gesture == Gesture.SWIPE_LEFT) {
                    // do something on left (backwards) swipe
                    return true;
                }
                return false;
            }
        });
        gestureDetector.setFingerListener(new GestureDetector.FingerListener() {
            @Override
            public void onFingerCountChanged(int previousCount, int currentCount) {
              // do something on finger count changes
            }
        });
        gestureDetector.setScrollListener(new GestureDetector.ScrollListener() {
            @Override
            public boolean onScroll(float displacement, float delta, float velocity) {
                // do something on scrolling
            }
        });
        return gestureDetector;
    }

    /*
     * Send generic motion events to the gesture detector
     */
    @Override
    public boolean onGenericMotionEvent(MotionEvent event) {
        if (mGestureDetector != null) {
            return mGestureDetector.onMotionEvent(event);
        }
        return false;
    }
}

偵測檢視區塊手勢

當您想要根據哪個畫面的焦點,執行不同動作時,可以在檢視層級偵測手勢。

以下範例會執行下列操作:

  1. 建立自訂的檢視畫面覆寫 dispatchGenericFocusedEvent() 方法。發生動作事件時,此方法會將動作事件傳送至手勢偵測工具。
  2. 將檢視畫面宣告為可聚焦,以便在其有焦點時偵測事件。
  3. 建立 GestureDetector 來實作事件監聽器來處理已識別的手勢。

當檢視畫面聚焦於檢視畫面時,手勢偵測器偵測到動作時,手勢偵測工具就會呼叫適當的事件監聽器。

/**
 * TextView that handles touchpad input (currently only TAP).
 */
public class TouchpadHandlingTextView extends TextView
        implements OnAttachStateChangeListener{

    private final GestureDetector mTouchDetector;

    public TouchpadHandlingTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mTouchDetector = createGestureDetector(context);
        // must set the view to be focusable
        setFocusable(true);
        setFocusableInTouchMode(true);
    }

    public TouchpadHandlingTextView(Context context) {
        this(context, null);
    }

    @Override
    public void onViewAttachedToWindow(View v) {
        requestFocus();
    }

    @Override
    public void onViewDetachedFromWindow(View v) {
    }

    /**
     * Pass a MotionEvent into the gesture detector
     */
    @Override
    public boolean dispatchGenericFocusedEvent(MotionEvent event) {
        if (isFocused()) {
            return mTouchDetector.onMotionEvent(event);
        }
        return super.dispatchGenericFocusedEvent(event);
    }

    /**
     * Create gesture detector that triggers onClickListener. Implement
     * onClickListener in your Activity and override
     * onClick() to handle the "tap" gesture.
     */
    private GestureDetector createGestureDetector(Context context) {
        GestureDetector gd = new GestureDetector(context);
        gd.setBaseListener(new GestureDetector.BaseListener() {

            @Override
            public boolean onGesture(Gesture gesture) {
                if (gesture == Gesture.TAP) {
                    return performClick();
                }
                return false;
            }
        });
        return gd;
    }
}