您的位置:首页 > 其它

GestureDetector +onTouch实现区域内滑动(事件分发)

2016-02-24 17:22 363 查看
以前都是用GestureDetector都是跟Activity的onTouchEvent方法结合,实现全屏幕的滑动捕获,而本次由于项目需要实现横幅广告轮播功能,轮播包括自动滚动和手动滑动,因此我打算在手动滑动上依旧采用GestureDetector去实现,与之前的不同,这次不能与onTouchEvent去组合了(是可以通过这种方式组合的,只是麻烦点),因为不需要全屏滑动,只有手在轮播图的区域内滑动才有效果,因此本次采取的是对轮播图区域绑定onTouchListener,然后将event传递到GestureDetector对象中代码如下:

viewFlipper.setOnTouchListener(new OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
return detector.onTouchEvent(event);
}
});


GestureDetector 需要重写下面几个方法:

@Override
public boolean onDown(MotionEvent e) {
// TODO Auto-generated method stub
return true;
}

@Override
public void onShowPress(MotionEvent e) {
// TODO Auto-generated method stub

}

@Override
public boolean onSingleTapUp(MotionEvent e) {
// TODO Auto-generated method stub
return false;
}

@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
// TODO Auto-generated method stub
return false;
}

@Override
public void onLongPress(MotionEvent e) {
// TODO Auto-generated method stub

}

@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {

return false;
}


最开始我这么写完之后将滑动效果写到onFling方法中,其他方法都是系统默认的,运行后发现没有响应,很是费解,然后回过头开始复习事件的分发机制,本来之前研究过,看来是没有研究透,后来又仔细研究了一下,发现原来是没有将onDown方法范围值设为true,只有设置为true,才能接到后续的事件(当然设置为true后,其view都不能在接收事件了,除非,父容器拦截);

下面复习一下ViewGroup和View的onTouch事件分发机制:

接收事件顺序:

Activity—->ViewGroup(页面布局)—->view或ViewGroup(页面子布局)

首先当Activity 收到down事件,会将事件发给viewgroup,viewgroup会判断自身是否拦截,如果拦截了则自身消费,之后的的move,up事件将交给所拦截的viewgroup处理(除非上一级进行了拦截,则会接收到取消事件),如果不拦截则向子布局传递事件,子view如果return true,则证明消费了改事件,以后的move,up事件将交给改view处理,除非上一级将move或up处理;如果所有布局均不消费该事件,则会

将所有view或viewgroup走一遍,而后执行Activity的onTouchEvent方法,如果所有视图层均未消费事件,则以后的move,up事件将全部由Activity消费,不再向下传递。(这也是为什么要将onDown返回值设为true的原因)。

另外,一个事件只能有一个视图消费,不能多个view或者viewgroup共同消费。

由于网上完整的事件分发机制已经太多太全了,所以本文介绍的比较浅显,如果大家有疑惑可以去网上搜索事件分发详解
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: