點擊事件分發(fā)
- ACTION_DOWN事件觸發(fā)時卸亮,會從Activity -> PhoneWindow -> DecorView -> ViewGroup -> View順序唠椭,逐層調(diào)用對應(yīng)的dispatchTouchEvent方法分發(fā)择克。
- 在View的dispatchTouchEvent中模蜡,常理會調(diào)用onTouchEvent顾瞪,在onTouchEvent方法中彻况,ACTION_DOWN時名扛,會檢查是否是長按,時長超過500毫秒則是長按括儒;在ACTION_UP時绕沈,會調(diào)用performOnClickInteral,依次調(diào)用onClick()帮寻,響應(yīng)點擊事件乍狐。如果重寫onTouch()方法,返回true固逗,則View的dispatchTouchEvent中浅蚪,有一個if判斷條件成立,會將boolean局部變量result置true烫罩,那么接下來一個if判斷中惜傲,該result為true,就不會調(diào)用onTouchEvent方法贝攒,因此該次觸摸事件則消費結(jié)束盗誊,不會再響應(yīng)onLongClick和onClick。如果重寫onLongClick()方法隘弊,返回true哈踱,則在onTouchEvent方法中,ACTION_DOWN時梨熙,檢查是長按后开镣,會調(diào)用onLongClick(),響應(yīng)長按事件串结,該方法返回true后哑子,會將mHasPerformedLongPress代表是否執(zhí)行了長按事件的boolean值置true;在ACTION_UP時肌割,調(diào)用performOnClickInteral前卧蜓,會先判斷mHasPerformedLongPress,為true把敞,則不調(diào)弥奸,為false,才調(diào)用奋早。因此盛霎,重寫onLongClick()方法,返回true時耽装,不會再響應(yīng)onClick愤炸。
點擊事件傳遞過程:
- ACTION_DOWN事件,Viewgroup的dispatchTouchEvent分發(fā)事件掉奄,onInterceptTouchEvent攔截事件规个,默認不攔截,繼續(xù)向下分發(fā)給子View,子View的dispatchTouchEvent分發(fā)事件诞仓,傳給子View的onTouchEvent缤苫,若返回true消費,則后面的ACTION_MOVE和ACTION_UP事件按順序繼續(xù)分發(fā)傳遞墅拭。
- 事件傳給子View的onTouchEvent時活玲,子View返回false,不消費事件谍婉,則事件回傳給ViewGroup的onTouchEvent來消費舒憾,以后的時間會按照ViewGoup的dispatchTouchEvent到onTouchEvent來傳遞消費。
- 當ViewGroup的onInterceptTouchEvent攔截事件后穗熬,則會傳遞給ViewGroup的onTouchEvent消費珍剑,以后的其他事件也會按照ViewGoup的dispatchTouchEvent到onTouchEvent來傳遞消費,不會再傳給子View死陆。
解決觸摸事件沖突:
- 外部攔截招拙。ViewGroup重寫onInterceptTouchEvent方法,默認不攔截措译,事件往下分發(fā)給子View别凤,若返回true,則攔截此次事件领虹,將事件傳給ViewGroup的onTouchEvent處理规哪。
- 內(nèi)部攔截。重寫子View的dispatchTouchEvent方法塌衰,方法中調(diào)用getParent().requestDisallowInterceptTouchEvent(true)方法诉稍,傳true則代表不希望ViewGroup攔截事件,傳false則代表希望ViewGroup攔截事件最疆。
- 內(nèi)部攔截杯巨。子View重寫onTouchEvent方法,返回true努酸,則子View消費該次事件服爷,返回false,該次事件返回給ViewGroup的onTouchEvent處理获诈。