到一些解釋android事件分發(fā)的巫湘,基本都是窮舉一些所有情況整幾個(gè)大圖,名詞概念搬一搬厕倍,也不說為什么會這樣寡壮,3個(gè)方法的牽扯關(guān)系究竟為何,很長讹弯,實(shí)戰(zhàn)或面試的時(shí)候能拿來用嗎况既?本人不才,認(rèn)為以下的偽代碼基本能搞定事件分發(fā)组民,為圖簡單Event參數(shù)都不要了棒仍,只解釋核心,自己自定義view的時(shí)候也可以直接跟著用邪乍,請賜教
public class IView{
public boolean dispatchTouchEvent() {
return onTouchEvent();
}
public boolean onTouchEvent() {
//可以通過setOnTouchListener等消費(fèi)則 return true return false;
}
}
public class IViewGroup extends IView {
public List<IView> childs = new ArrayList<>();
//注釋1:理解事件分發(fā)有個(gè)容易被忽視的前提就是ViewGroup是繼承的View
//雖然ViewGroup沒有實(shí)現(xiàn)onTouchEvent
//但是super.dispatchTouchEvent調(diào)用的就是super.onTouchEvent
// 即他自己的onTouchEvent
public boolean onInterceptTouchEvent() {
return false;//
}
@Override
public boolean dispatchTouchEvent() {
if (true) {
//這個(gè)true就是
// final int action = ev.getAction();
// final int actionMasked = action & MotionEvent.ACTION_MASK;
// actionMasked == MotionEvent.ACTION_DOWN
resetTouchState();//FLAG_DISALLOW_INTERCEPT==false
//這里的意思就是findid后 直接調(diào)requestDisallowInterceptTouchEvent沒有暖用
//此處被重置 為false需要在這個(gè)if后面調(diào)
}
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;
//只要有一個(gè)child View的dispatchTouchEvent(注釋1)返回true
//已經(jīng)return那么后續(xù)的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;
}
}
小總結(jié) 背了下面這個(gè)偽代碼
這個(gè)執(zhí)行順序和相互關(guān)系隨便問
if (降狠!禁止打斷()&& 是否打斷()) {
viewgroup可以要了
}else{
for (int i = 0; i < childs.size(); i++) {
if (somechild.要//即somechild.onTouchEvent) {
return true;
}
}
}
return viewgroup可以要了
小總結(jié)
<font color=RED face="楷體" size=5>
父想要咋辦 1.使!禁止打斷()&& 是否打斷() 為true 2. child.要全為false
子想要咋辦 1.禁止打斷為true 2.要的那個(gè)view的child.要為true
</font>
<font color=#123456 face="楷體" size=5>
完事 so easy 如果還沒有概括不了情況 歡迎指正
另外誰能告訴我這個(gè)簡書文字怎么不變色~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;
}
}
}
//當(dāng)子View沒有捕獲down事件時(shí),ViewGroup自身處理吕晌。這里處理的Touch事件包含Down蛋褥、Up和Move
if(mTarget==null){
return super.dispatchTouchEvent(ev);
}
//...其他處理,在此不管
if(onInterceptTouchEvent()){
//...其他處理睛驳,在此不管
}
//這一步在Action_Down中是不會執(zhí)行到的烙心,只有Move和UP才會執(zhí)行到膜廊。
return mTarget.dispatchTouchEvent(ev);
}