Gestos táctiles

Es posible acceder a datos sin procesar desde el panel táctil de Glass con el SDK de Android.

Sin embargo, GDK proporciona un detector de gestos que detecta automáticamente los gestos comunes en Glass, que incluyen presionar, deslizar y desplazarse.

Además, de forma predeterminada, los gestos simples se traducen en eventos de pad direccional para procesarlos sin usar un detector de gestos.

Detección de gestos como eventos clave del pad direccional

De forma predeterminada, el sistema Glass convierte los gestos simples en eventos clave del pad direccional. Esto te permite escuchar eventos onKeyDown() y onKeyUp() en actividades o vistas para procesar los siguientes gestos como teclas de pad direccional:

El siguiente fragmento detecta cuándo los usuarios presionan el panel táctil:

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

Un método para detectar presiones en vistas individuales es implementar OnClickListener en la vista. Cuando los usuarios presionan el panel táctil (traslado como un clic con el botón central del pad direccional) con la vista enfocada, esta puede controlar el evento con una 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
    }
}

Cómo detectar gestos con un detector de gestos

Los detectores de gestos te permiten detectar gestos simples, además de gestos más complejos, como los que usan varios dedos o el desplazamiento. Los gestos complejos no tienen una tecla de pad direccional correspondiente.

El GestureDetector proporciona interfaces de objeto de escucha que puedes implementar para recibir una notificación de un Gesto.

Cómo detectar gestos a nivel de la actividad

La detección de gestos a nivel de la actividad es apropiada cuando no te importa qué parte de tu IU está enfocada. Por ejemplo, si quieres que aparezca un menú cuando los usuarios presionan el panel táctil, sin importar la vista enfocada, deberías controlar el MotionEvent dentro de la actividad.

En el ejemplo siguiente, se realizan estas acciones:

  1. Crea un GestureDetector que implementa objetos de escucha para procesar gestos reconocidos.
  2. Anula el método onGenericMotionEvent() de la actividad para pasar los eventos de movimiento al método onMotionEvent() del detector de gestos.

Cuando ocurre un evento de movimiento, el sistema lo pasa al detector de gestos. Si se reconoce, el detector de gestos notifica al objeto de escucha correspondiente para que procese el 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;
    }
}

Detecta gestos a nivel de la vista

La detección de gestos a nivel de la vista es apropiada cuando deseas realizar diferentes acciones según la vista enfocada.

En el ejemplo siguiente, se realizan estas acciones:

  1. Crea una vista personalizada que anula el método dispatchGenericFocusedEvent(). Cuando ocurre un evento de movimiento, este método pasa el evento de movimiento al detector de gestos.
  2. Declara que la vista es enfocable para que detecte eventos cuando esté enfocada.
  3. Crea un GestureDetector que implemente objetos de escucha para procesar gestos reconocidos.

Cuando el detector de gestos reconoce un movimiento mientras la vista está en foco, llama al objeto de escucha correspondiente.

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