Android 触摸事件分发

看了N多文章介绍事件分发,不如自己写一个例子更透彻。
知识点提要:
1.View 具有的方法:
dispatchTouchEvent(MotionEvent event);(分发)true—->消费
onTouchEvent(MotionEvent event);(触摸)
2.ViewGroup 具有的方法:
dispatchTouchEvent(MotionEvent event);(分发)true—->消费
onTouchEvent(MotionEvent event);(触摸)
onInterceptTouchEvent(MotionEvent ev);(拦截)
3.Activity具有的方法:
dispatchTouchEvent(MotionEvent event);(分发)true—->消费

根据以上,上主要代码:
MainActivity重写onCreate 和dispatchTouchEvent:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.myRelativeLayout).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "myRelativeLayout.onClick");
}
});
findViewById(R.id.myTextView).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d(TAG, "myTextView.onClick");
}
});
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
Log.d(TAG, "dispatchTouchEvent");
return super.dispatchTouchEvent(ev);
}

MyRelativeLayout重写onTouchEvent(),onInterceptTouchEvent(),dispatchTouchEvent()。

public class MyRelativeLayout extends RelativeLayout {
    public String TAG = getClass().getName();
 public MyRelativeLayout(Context context) {
        super(context);
    }

    public MyRelativeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public MyRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.d(TAG, "onTouchEvent");
        return super.onTouchEvent(event);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        Log.d(TAG, "onInterceptTouchEvent");
        return super.onInterceptTouchEvent(ev);
       // return true;
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        Log.d(TAG, "dispatchTouchEvent");
        return super.dispatchTouchEvent(ev);
    }
}

MyTextView 重写dispatchTouchEvent(MotionEvent event),
onTouchEvent(MotionEvent event);

public class MyTextView extends TextView {
    public String TAG = getClass().getName();

    public MyTextView(Context context) {
        super(context);
    }
    public MyTextView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public MyTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.d(TAG, "onTouchEvent");
        return super.onTouchEvent(event);

    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {
        Log.d(TAG, "dispatchTouchEvent");
        return super.dispatchTouchEvent(event);
    }
}

1.触摸MyTextView:
MainActivity: dispatchTouchEvent–down
MyRelativeLayout:dispatchTouchEvent–down
MyRelativeLayout: onInterceptTouchEvent–down
MyTextView: dispatchTouchEvent–down
MyTextView: onTouchEvent–down
MainActivity: dispatchTouchEvent–up
MyRelativeLayout: dispatchTouchEvent–up
MyRelativeLayout: onInterceptTouchEvent–up
MyTextView: dispatchTouchEvent–up
MyTextView: onTouchEvent–up
MainActivity: myTextView.onClick

2.修改MyRelativeLayout onInterceptTouchEvent 返回true结果:
MainActivity: dispatchTouchEvent
MyRelativeLayout: dispatchTouchEvent
MyRelativeLayout: onInterceptTouchEvent
MyRelativeLayout: onTouchEvent
MainActivity: dispatchTouchEvent
MyRelativeLayout: dispatchTouchEvent
MyRelativeLayout: onTouchEvent
MainActivity: myRelativeLayout.onClick

3.修改MyRelativeLayout dispatchTouchEvent返回true结果:
MainActivity: dispatchTouchEvent
MyRelativeLayout: dispatchTouchEvent
MainActivity: dispatchTouchEvent
MyRelativeLayout: dispatchTouchEvent

4.修改MyTextView dispatchTouchEvent返回true结果:
MainActivity: dispatchTouchEvent
MyRelativeLayout: dispatchTouchEvent
MyRelativeLayout: onInterceptTouchEvent
MyTextView: dispatchTouchEvent
MainActivity: dispatchTouchEvent
MyRelativeLayout: dispatchTouchEvent
MyRelativeLayout: onInterceptTouchEvent
MyTextView: dispatchTouchEvent

5.修改MyRelativeLayout dispatchTouchEvent返回false结果:
MainActivity: dispatchTouchEvent
MyRelativeLayout: dispatchTouchEvent
MainActivity: dispatchTouchEvent

6.修改MyTextView dispatchTouchEvent返回false结果:
MainActivity: dispatchTouchEvent
MyRelativeLayout: dispatchTouchEvent
MyRelativeLayout: onInterceptTouchEvent
MyTextView: dispatchTouchEvent
MyRelativeLayout: onTouchEvent
MainActivity: dispatchTouchEvent
MyRelativeLayout: dispatchTouchEvent
MyRelativeLayout: onTouchEvent
MainActivity: myRelativeLayout.onClick

对比1和2,结论一:父View的onInterceptTouchEvent 返回true则touch不会再传递给子View,该事件由父View处理。
对比1和3、4,结论二:父View的dispatchTouchEvent 返回true,则touch不会再往下传递,up事件和down事件一样,父View接收up事件。
对比1和3、5,结论三:父View的dispatchTouchEvent 返回false,则touch不会再往下传递,up事件也不会再交给该父View处理。
对比1和3、5、6,结论四:子View的dispatchTouchEvent 返回false,则touch不会再往下传递,up事件也不会交给该子View处理,该事件交给父View处理,且不会up事件传递不会调用该父View的onInterceptTouchEvent 事件。
对比1和2、6、结论五:父View的onInterceptTouchEvent 返回true和子View的dispatchTouchEvent 返回false效果类似,区别只在于后者会执行一次dispatchTouchEvent 事件。
对比1和4、6,结论六:子View的dispatchTouchEvent返回true和false区别:返回true,不会执行父View的onTouchEvent方法,up事件父View会执行onInterceptTouchEvent事件;返回false,会执行父View的onTouchEvent方法,up事件父View不会执行onInterceptTouchEvent事件。
结论不太好记,
总结一下就是,父dispatchTouchEvent 返回false ,事件不会传递给子View,该事件会被父View的父View来处理调用onTouchEvent方法;
子View dispatchTouchEvent 返回true,该事件会被丢弃,不会调用onTouchEvent方法,touch事件会被丢弃,想继续传递应该返回super.dispatchTouchEvent ;
父View 调用onInterceptTouchEvent 子View不会接受到该事件,由该父View处理,up事件不会受到影响。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值