onInterceptTouchEvent用于拦截touch事件
OnTouchEvent 处理touch事件
onInterceptTouchEvent主要用于拦截touch事件,当返回值为true时,该事件不向下层view传递,而是本层onTouchEvent中处理touch事件。返回值为false时,事件传递到下层View的onInterceptTouchEvent
onTouchEvent,返回值为true时,touch事件被消耗不会向上层传递,返回false时,touch事件继续向上层view中的OntouchEvent传递,同时下次touch事件不会再传递到本层view处理
Demo实例
容器父View
- public class MyLayout extends ViewGroup {
- private int lastX;
- private int lastY;
- private int thresholdX=100;
- private boolean isDrag=false;
- public MyLayout(Context context, AttributeSet attrs) {
- // TODO Auto-generated constructor stub
- super(context, attrs);
- }
- public MyLayout(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- // TODO Auto-generated constructor stub
- }
- @Override
- protected void onLayout(boolean changed, int l, int t, int r, int b) {
- // TODO Auto-generated method stub
- for (int i = 0; i < getChildCount(); i++) {
- View child=getChildAt(i);
- child.layout(0, 0, child.getMeasuredWidth(), child.getMeasuredHeight());
- }
- }
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- // TODO Auto-generated method stub
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- for (int i = 0; i <getChildCount(); i++) {
- View child=getChildAt(i);
- //child.measure(widthMeasureSpec,heightMeasureSpec);
- LayoutParams lp=(LayoutParams)child.getLayoutParams();
- child.measure(getChildMeasureSpec(widthMeasureSpec, 0, lp.width), getChildMeasureSpec(heightMeasureSpec,0,lp.height));
- }
- }
- @Override
- public boolean dispatchTouchEvent(MotionEvent ev) {
- // TODO Auto-generated method stub
- return super.dispatchTouchEvent(ev);
- }
- @Override
- public boolean onInterceptTouchEvent(MotionEvent ev) {
- // TODO Auto-generated method stub
- switch (ev.getAction()) {
- case MotionEvent.ACTION_DOWN:
- Log.i("debug", "-----onInterceptTouchEvent-------Aciton_down----------");
- break;
- case MotionEvent.ACTION_MOVE:
- Log.i("debug", "--------onInterceptTouchEvent----Aciton_move----------");
- break;
- case MotionEvent.ACTION_CANCEL:
- Log.i("debug", "---------onInterceptTouchEvent---Aciton_cancel----------");
- break;
- case MotionEvent.ACTION_UP:
- Log.i("debug", "-------onInterceptTouchEvent-----Aciton_up----------");
- break;
- default:
- break;
- }
- return false;
- }
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- // TODO Auto-generated method stub
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- Log.i("debug", "-----mylayout-------Aciton_down----------");
- break;
- case MotionEvent.ACTION_MOVE:
- Log.i("debug", "------mylayout-----Aciton_move----------");
- break;
- case MotionEvent.ACTION_CANCEL:
- Log.i("debug", "------mylayout-----Aciton_cancel----------");
- break;
- case MotionEvent.ACTION_UP:
- Log.i("debug", "------mylayout-----Aciton_up----------");
- break;
- default:
- break;
- }
- return true;
- }
- public class CustomeImageView extends ImageView {
- public CustomeImageView(Context context, AttributeSet attrs) {
- super(context, attrs);
- // TODO Auto-generated constructor stub
- }
- public CustomeImageView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- // TODO Auto-generated constructor stub
- }
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- // TODO Auto-generated method stub
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- Log.i("debug", "-------imageview-----Aciton_down----------");
- break;
- case MotionEvent.ACTION_MOVE:
- Log.i("debug", "-------ImageView-----Aciton_move----------");
- break;
- case MotionEvent.ACTION_CANCEL:
- Log.i("debug", "-------ImageView-----Aciton_cancel----------");
- break;
- case MotionEvent.ACTION_UP:
- Log.i("debug", "--------ImageView----Aciton_up----------");
- break;
- default:
- break;
- }
- return false;
- }
- }
步骤二,MyLayout中onInterceptTouchEvent返回false,子View中的onTouchEvent能接受到触摸事件,Log
步骤三,在子VIew中测试OnTouchEvent返回值f(前提触摸事件可以传递到子view)若返回false,在一次touch事件中(Action_down开始Action_up结束)子view接受一次down事件,并把事件向上层传递
步骤三,在子VIew中测试OnTouchEvent返回值f(前提触摸事件可以传递到子view)若返回true,子View可以接受touch的所有事件,并且事件不会向上层传递
总结,android触摸事件传递机制,首先是dispatchTouchEvent根据onInterceptTouchEvent的返回值确定事件是分发给自己还是分配给子VIew的dispatchTouchEvent,子View在决定事件是否继续向下传递,事件传递到最后一个view时,调用该view的onTouchEvent函数去处理触摸事件,若函数返回true,则以后就会在此处理,不会向上层的onTouchEvent传递。返回false,就会传递到上一层的onTouchEvent,根据返回值决定是否处理事件,