安卓监听触摸事件,以及各种按键 处理

 在做自定义弹窗的时候遇到的问题,如果不继承Dialog 或者popwindow 自己写的通过 getWindow的decorView 给decorView view 动态添加View 和移除View实现弹窗会出现返回按键如果是弹窗情况下需要关闭弹窗(即移除View) ,那么怎么监听返回按键?这里看了dialog 和popwindow 发现了写规律,即两者都实现了Window.Callback,以及 KeyEvent.Callback, 这里KeyEvent.Callback有三个实现方法:

onKeyUp :抬起
onKeyLongPress:长按
onKeyDown:按下
而Window.Callback,就比较多了,这里我就不解释了,主要说两个地方:
dispatchKeyEvent :分发关键事件(这里指的就是home键盘,或者返回键,以及音量键,电源键等这些是关键事件)
dispatchTouchEvent:分发触摸事件,这里是分发触摸事件
如果想拦截手机的返回按键则需要在弹窗展示的时候让窗口window 处理callback到这里,
即window.setCallback( );是自己的这个回调,不然一直都是Activity在处理按键,以及触摸事件

1.在show的时候activity.getWindow().setCallBack(this) 自己的实现

2.然后重写 dispatchKeyEvent  让处理分发

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        if (xWindow.superDispatchKeyEvent(event)) {
            return true;
        }
        return event.dispatch(this, xWindow.getDecorView() != null
                ? xWindow.getDecorView().getKeyDispatcherState() : null, this);
    }

3.分发后就到了KeyEvent.CallBack的onKeyDown按下事件

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK) {
        event.startTracking();
        return true;
    }
    return false;
}

4.按下事件处理过后就是抬起,这里就判断如果当前在展示,就关闭弹窗(移除View),然后消耗本次事件

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_BACK && event.isTracking()
            && !event.isCanceled()) {
        if (isShowing) {
            dismiss();
            return true;
        }
        return false;
    }
    return false;
}

 

5.关闭弹窗后不要忘记把窗体的回调还给Activity 的Callback
  xWindow.setCallback(Activity);

6.到此为止关于按键就处理完了,但是还有问题,Callback不仅仅处理按键,还处理了触摸事件,如果不做处理
那么在屏幕触就无效了,无论怎么触摸都没响应,主要是因为
dispatchTouchEvent没做处理,这里还需要做处理:

 

 

@Override
public boolean dispatchTouchEvent(MotionEvent event) {
    if (xWindow.superDispatchTouchEvent(event)) {
        return true;
    }
    return false;
}

 

到这里位置就全部处理完毕了

上文中代码 xWindow变量就是从Activity中gewindow()获取到的window对象

 

安卓监听触摸事件,以及各种按键 处理

上一篇:[PHP]引用语法


下一篇:CSS字体样式属性