Accessing raw data from the Glass touchpad is possible with the Android SDK.
However, the GDK provides a gesture detector that automatically detects common gestures on Glass, including tapping, swiping, and scrolling.
In addition, simple gestures are translated into D-pad events by default for easy processing without using a gesture detector.
By default, the Glass system translates simple gestures into D-pad key events. This lets you listen for onKeyDown()
and onKeyUp()
events on activities or views to process the following gestures as D-pad keys:
KEYCODE_DPAD_CENTER
.KEYCODE_CAMERA
.KEYCODE_BACK
.The following snippet detects when users tap down on the 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);
}
}
A method to detect taps on individual views is to implement OnClickListener
for the view. When users tap the touchpad (translated as a D-pad center button click) with the view in focus, the view can handle the event with an 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
}
}
Gesture detectors let you detect simple gestures as well as more complex gestures, such as those that use multiple fingers or scrolling. Complex gestures do not have a corresponding D-pad key.
The GestureDetector provides listener interfaces that you can implement to be notified of a Gesture.
Detecting gestures at the activity level is appropriate when you don’t care what part of your UI has focus. For example, if you want to bring up a menu when users tap the touchpad, regardless of what view has focus, you’d handle the MotionEvent
inside the activity.
The following example:
GestureDetector
that implements listeners to process recognized gestures.onGenericMotionEvent()
method to pass the motion events to the gesture detector’s onMotionEvent()
[TODO: ADD LINK] method.When a motion event occurs, the system passes it to the gesture detector. If recognized, the gesture detector notifies the appropriate listener to process the event.
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;
}
}
Detecting gestures at the view level is appropriate when you want to do different things depending on what view has focus.
The following example:
dispatchGenericFocusedEvent()
method. When a motion event occurs, this method passes the motion event to the gesture detector.GestureDetector
[TODO: ADD LINK] that implements listeners to process recognized gestures.When the gesture detector recognizes a motion while the view is in focus, the gesture detector calls the appropriate listener.
/**
* 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;
}
}
Portions of this page are reproduced from work created and shared by Google and used according to terms described in the Creative Commons 4.0 Attribution License.