1.源码的查看
1.开始分发:重写dispatchTouchEvent
1. 先了解事件分发
事件:一般手指触碰屏幕:至少产生两个事件(按下DOWN,起来UP)
分发:
2.事件传递层级
3.View添加到DecorView流程
重写分发方法,这里是分发的开始(派遣):dispatchTouchEvnet
/**
* 这个是事件开始,肯定会执行的,至少两次,点击起来两次,移动的话多次
* @param ev
* @return true表示事件消费了,即点击按钮没反应,因为没事件了,false表示事件没有消费,即点击按钮可以执行
*/
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {//派遣点击事件
Log.d(TAG, "dispatchTouchEvent: "+i++);
return super.dispatchTouchEvent(ev);
}
界面中有一个按钮,监听setOnTouchListener
findViewById(R.id.bt).setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.d(TAG, "onTouch: down");
break;
case MotionEvent.ACTION_MOVE:
Log.d(TAG, "onTouch: move");
break;
case MotionEvent.ACTION_UP:
Log.d(TAG, "onTouch: up");
break;
case MotionEvent.ACTION_CANCEL:
Toast.makeText(MainActivity.this, "cancel", Toast.LENGTH_SHORT).show();
break;
}
return false;
}
});
当点击按钮的时候(这里有停顿一会),会执行
dispatchTouchEvent返回的是一个Boolean值,当返回为true的时候,事件表示被消费了:意味没有事件了,所以点击按钮的时候没有反应(这里将其返回值设置为true)
执行结果:
(其实手指是执行了:DOWN,MOVE,UP),
2.查看返回值:点进去
由于我们点击屏幕的时候,会执行一次DOWN,所以onUserInteraction会被执行,它里面是一个空方法
3.查看getWindow().superDispatchTouchEvent(ev)
点进去:它是一个公共的抽象方法,返回的是一个boolean值
查看:它只有一个唯一的实现类PhoneWindow,所以我们找到PhoneWindow类
双击shift,输入phoneWindow,找到对应的类
4.查看mDecor.superDispatchTouchEvent
mDicor是DecorView,而这个DecorView是Window持有的,点进去
再点进去,最终由ViewGroup里的DispatchTouchEvent实现,它返回为true,就结束了
当返回为false的时候,返回onTouchEvent(ev)的boolean值
5.onTouchEvent源码:
先查看mWindow.shouldCloseOnTouch
mWindow就是Window,找到里面的这个方法
满足下面三个就返回true(个人感觉这三个肯定有的,希望大神help me):
1.流程图
里面红色部分onTouchEvent的流程图
2.讲解:
1.dispatchOnTouchEvent的点击:
点击MainActivity时会触发dispatchOnTouchEvent两次(是DOWN与UP)。然后点击,移动,在松开:就会触发多次dispatchOnTouchEvent(应该是DOWN,……MOVE……MOVE……UP)
2.dispatchOnTouchEvent的返回值
它返回一个boolean值。当返回为true的时候,点击Activity上的Button,无效不响应
因为事件被消费了(手指点击下去的时候会触发触摸事件,一般为DOWN、UP或DOWN、MOVE、UP):