使用 Android SDK 可以通过 Glass 触控板访问原始数据。
不过,GDK 提供了一个手势检测器,可自动检测 Glass 上的常见手势,包括点按、滑动和滚动。
此外,默认情况下,简单手势会转换为方向键事件,以便在不使用手势检测器的情况下轻松处理。
检测作为方向键按键事件的手势
默认情况下,Glass 系统会将简单的手势转换为方向键按键事件。这样,您就可以监听 activity 或视图上的 onKeyDown()
和 onKeyUp()
事件,以便将以下手势处理为方向键:
- 点按“翻译”图标
KEYCODE_DPAD_CENTER
。 - 按下相机按钮可转换为
KEYCODE_CAMERA
。 - 向下滑动即可翻译成
KEYCODE_BACK
。
以下代码段可检测用户点按触控板的时间:
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
。当用户点按视图(转换为方向键中间按钮点击)且视图获得焦点时,视图可以使用 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
}
}
使用手势检测器检测手势
借助手势检测器,您可以检测简单手势以及更复杂的手势,例如使用多个手指或滚动的手势。复杂手势没有对应的方向键。
GestureDetector 提供了监听器接口,您可以通过实现这些接口来接收手势通知。
检测 activity 级别手势
如果您并不关心界面的哪个部分获得焦点,那么适合在 activity 级别检测手势。例如,如果您想在用户点按触控板时调出菜单,而不考虑哪个视图获得焦点,则应在 activity 内部处理 MotionEvent
。
下面的示例:
- 创建一个
GestureDetector
,用于实现监听器以处理识别出的手势。 - 替换 activity 的
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;
}
}
检测视图级别手势
如果您想根据聚焦的视图执行不同的操作,在视图级别检测手势是合适的。
下面的示例:
- 创建会替换
dispatchGenericFocusedEvent()
方法的自定义视图。发生动作事件时,此方法会将动作事件传递给手势检测器。 - 将视图声明为可聚焦,以便它在获得焦点时检测事件。
- 创建一个
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;
}
}