GestureDetector和onTouchEvent

1、在处理触摸事件时,activity首先会调用DispatchTouchEvent,

    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            onUserInteraction();
        }
        if (getWindow().superDispatchTouchEvent(ev)) {
            return true;
        }
        return onTouchEvent(ev);
    }

可以看到,该方法会先调用onUserInteraction,此处不会拦截触摸事件,但是getWindow().superDispatchTouchEvent(ev)为true的话,则会拦截到触摸事件。

什么情况下该事件为true?通过javadoc可以看到:

Used by custom windows, such as Dialog, to pass the touch screen event further down the view hierarchy. Application developers should not need to implement or call this.

Parameters:
即类似Dialog的控件可能返回true。另外通过尝试,如果view是嵌在scrollview里,该方法同样会返回true,这样activity就不会收到onTouchEvent事件。

解决办法是在activity里重写dispatchTouchEvent方法,提前调用view的onTouchEvent方法:

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
gd.onTouchEvent(ev);//此处为GestureDetector的方法
return super.dispatchTouchEvent(ev);
}


2、GestureDetector的用法:

view可以通过onTouch事件来获取基本的触摸操作,(实现onTouchListener),但是对于双击、fling等较为复杂的手势,则需要Gesturedetector来实现:

Gesturedetector里有两个接口OnGestureListener和OnDoubleTapListener,如果使用这两个接口则需要实现所有的方法,android的framework为了简化代码,在GestureDetector里加了一个静态的内部类,实现了两个接口,每个方法都是简单的返回false。因此我们我们可以只继承该类,重写 某几个方法即可:

private class onDoubleClick extends GestureDetector.SimpleOnGestureListener {

@Override
public boolean onDoubleTap(MotionEvent e) {
// TODO Auto-generated method stub
// return super.onDoubleTap(e);
scaleImgOnDoubleClick();
mTitleLayout.setVisibility(View.GONE);
return true;
}


@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
// TODO Auto-generated method stub
showOrHideTitle();
return super.onSingleTapConfirmed(e);
}

}

在使用时,我们需要把onDoubleClick作为listener传入到GestureDetector的构造方法里,然后再onTouchEvent里调用GestureDetector的onTouchEvent方法即可,当然如果遇到上述所说onTouchEvent被拦截时,则需要重写DispatchTouchEvent,提前传入MotionEvent即可



posted @ 2013-03-25 14:19  tanqiantot  阅读(1298)  评论(0编辑  收藏  举报