到一些解释android事件分发的,基本都是穷举一些所有情况整几个大图,名词概念搬一搬,也不说为什么会这样,3个方法的牵扯关系究竟为何,很长,实战或面试的时候能拿来用吗?本人不才,认为以下的伪代码基本能搞定事件分发,为图简单Event参数都不要了,只解释核心,自己自定义view的时候也可以直接跟着用,请赐教
public class IView{
public boolean dispatchTouchEvent() {
return onTouchEvent();
}
public boolean onTouchEvent() {
//可以通过setOnTouchListener等消费则 return true return false;
}
}
public class IViewGroup extends IView {
public List<IView> childs = new ArrayList<>();
//注释1:理解事件分发有个容易被忽视的前提就是ViewGroup是继承的View
//虽然ViewGroup没有实现onTouchEvent
//但是super.dispatchTouchEvent调用的就是super.onTouchEvent
// 即他自己的onTouchEvent
public boolean onInterceptTouchEvent() {
return false;//
}
@Override
public boolean dispatchTouchEvent() {
if (true) {
//这个true就是
// final int action = ev.getAction();
// final int actionMasked = action & MotionEvent.ACTION_MASK;
// actionMasked == MotionEvent.ACTION_DOWN
resetTouchState();//FLAG_DISALLOW_INTERCEPT==false
//这里的意思就是findid后 直接调requestDisallowInterceptTouchEvent没有暖用
//此处被重置 为false需要在这个if后面调
}
if (!FLAG_DISALLOW_INTERCEPT && onInterceptTouchEvent()) {
//只有FLAG_DISALLOW_INTERCEPT为false才去判断onInterceptTouchEvent
super.dispatchTouchEvent();//注释1
} else {
for (int i = 0; i < childs.size(); i++) {
if (childs.get(i).dispatchTouchEvent()) {
return true;
//只要有一个child View的dispatchTouchEvent(注释1)返回true
//已经return那么后续的view也拿不到 super(他自己)也拿不到
}
}
}
return super.dispatchTouchEvent();
}
private boolean FLAG_DISALLOW_INTERCEPT = false; //是否禁止打断
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
FLAG_DISALLOW_INTERCEPT = disallowIntercept;
//如果viewgroup有父就 parent.requestDisallowInterceptTouchEvent(disallowIntercept)
}
public void resetTouchState() {
FLAG_DISALLOW_INTERCEPT = false;
}
}
小总结 背了下面这个伪代码
这个执行顺序和相互关系随便问
if (!禁止打断()&& 是否打断()) {
viewgroup可以要了
}else{
for (int i = 0; i < childs.size(); i++) {
if (somechild.要//即somechild.onTouchEvent) {
return true;
}
}
}
return viewgroup可以要了
小总结
<font color=RED face="楷体" size=5>
父想要咋办 1.使!禁止打断()&& 是否打断() 为true 2. child.要全为false
子想要咋办 1.禁止打断为true 2.要的那个view的child.要为true
</font>
<font color=#123456 face="楷体" size=5>
完事 so easy 如果还没有概括不了情况 欢迎指正
另外谁能告诉我这个简书文字怎么不变色~2333
</font>
记住上面基本就可以了 如果你还想考虑move down up
如果你还想考虑到down move
View mTarget=null;//保存捕获Touch事件处理的View
public boolean dispatchTouchEvent(MotionEvent ev) {
//....其他处理,在此不管
if(ev.getAction()==KeyEvent.ACTION_DOWN){
//每次Down事件,都置为Null
if(FLAG_DISALLOW_INTERCEPT ||!onInterceptTouchEvent()){
mTarget=null;
View[] views=getChildView();
for(int i=0;i<views.length;i++){
if(views[i].dispatchTouchEvent(ev))
mTarget=views[i];
return true;
}
}
}
//当子View没有捕获down事件时,ViewGroup自身处理。这里处理的Touch事件包含Down、Up和Move
if(mTarget==null){
return super.dispatchTouchEvent(ev);
}
//...其他处理,在此不管
if(onInterceptTouchEvent()){
//...其他处理,在此不管
}
//这一步在Action_Down中是不会执行到的,只有Move和UP才会执行到。
return mTarget.dispatchTouchEvent(ev);
}
网友评论