Gestos de toque

É possível acessar dados brutos usando o touchpad do Google Glass com o SDK do Android.

No entanto, o GDK oferece um detector de gestos que detecta gestos comuns no Google Glass automaticamente, incluindo toques em gestos de deslizar e rolagem.

Além disso, os gestos simples são convertidos em eventos do botão direcional por padrão para fácil processamento sem usar um detector de gestos.

Detectar gestos como eventos de botão direcional

Por padrão, o sistema Glass converte gestos simples em eventos de botão direcional. Isso permite detectar eventos onKeyDown() e onKeyUp() em atividades ou visualizações para processar os seguintes gestos como teclas direcionais:

O snippet a seguir detecta quando os usuários tocam no touchpad:

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);
    }
}

Um método para detectar toques em visualizações individuais é implementar OnClickListener para a visualização. Quando os usuários tocam no touchpad (traduzidos como um clique no botão central do botão direcional) com a visualização em foco, ela pode processar o evento com uma 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
    }
}

Como detectar gestos com um detector

Os detectores de gestos permitem detectar gestos simples e gestos mais complexos, como aqueles que usam vários dedos ou a rolagem. Gestos complexos não têm uma tecla D-pad correspondente.

O GestureDetector fornece interfaces de listener que você pode implementar para receber notificações de um Gesture.

Como detectar gestos no nível da atividade

A detecção de gestos no nível da atividade é apropriada quando você não se importa qual parte da IU está em foco. Por exemplo, caso você queira mostrar um menu quando os usuários tocam no touchpad, independentemente de qual visualização está em foco, você precisa processar a classe MotionEvent dentro da atividade.

No exemplo a seguir:

  1. Cria um GestureDetector que implementa listeners para processar gestos reconhecidos.
  2. Modifica o método onGenericMotionEvent() da atividade para transmitir os eventos de movimento para o método onMotionEvent() do detector de gestos.

Quando um evento de movimento ocorre, o sistema o transmite ao detector de gestos. Se reconhecido, o detector de gestos vai notificar o listener apropriado para processar o evento.

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;
    }
}

Como detectar gestos no nível da visualização

A detecção de gestos no nível da visualização é adequada quando você quer fazer coisas diferentes dependendo de qual visualização está em foco.

No exemplo a seguir:

  1. Cria uma visualização personalizada que substitui o método dispatchGenericFocusedEvent(). Quando um evento de movimento ocorre, esse método transmite o evento de movimento para o detector de gestos.
  2. Declara a visualização como focalizável para detectar eventos quando ela estiver em foco.
  3. Cria um GestureDetector que implementa listeners para processar gestos reconhecidos.

Quando o detector de gestos reconhece um movimento enquanto a visualização está em foco, ele chama o listener apropriado.

/**
 * 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;
    }
}