Android自定義事件分發(fā)順序?qū)崿F(xiàn)思路

事件分發(fā)機(jī)制大家應(yīng)該都熟記于心瑟俭,默認(rèn)事件分發(fā)是逆序的谒臼,有哪些方法可以修改分發(fā)順序价匠?

修改事件分發(fā)順序的話墨微,在日常開(kāi)發(fā)中基本遇不到,因?yàn)楝F(xiàn)在的逆序遍歷陪捷,是跟View的層級(jí)顯示相匹配的回窘,隨便更改反而不太合理。

如果非要修改這個(gè)順序市袖,很多同學(xué)首先會(huì)想到:重寫dispatchTouchEvent()方法啡直,然后在里面一個(gè)for循環(huán),從0開(kāi)始一個(gè)個(gè)調(diào)用子View的dispatchTouchEvent()苍碟。

這個(gè)方法酒觅,不是說(shuō)絕對(duì)不行,只是你要做的事情很多微峰,就比如觸摸坐標(biāo)的轉(zhuǎn)換

我們都知道舷丹,View Group在分派事件的時(shí)候,會(huì)檢查子View是否應(yīng)用過(guò)屬性動(dòng)畫(huà)的(位移蜓肆、縮放颜凯、旋轉(zhuǎn)等)谋币,如果有的話還要把坐標(biāo)給映射回去。接著症概,還會(huì)把相對(duì)于這個(gè)View Group本身的觸摸坐標(biāo) 轉(zhuǎn)換成 相對(duì)于對(duì)應(yīng)子View的觸摸坐標(biāo)蕾额。

這樣說(shuō)可能有點(diǎn)繞,
舉個(gè)例子彼城,比如:當(dāng)手指在屏幕中按下凡简,ViewGroup中收到的event坐標(biāo)(getX,getY)假設(shè)是【500,500】,剛好在這個(gè)位置上有個(gè)子View精肃,那接下來(lái)肯定會(huì)把事件傳給這個(gè)子View的dispatchTouchEvent,這時(shí)候如果坐標(biāo)不轉(zhuǎn)換直接傳的話帜乞,那子View收到的event坐標(biāo)(getX,getY)也是【500,500】司抱,這明顯是不對(duì)的,正確的坐標(biāo)應(yīng)該要分別減去它的left和top黎烈。

這看起來(lái)好像沒(méi)什么大的影響习柠,但如果你的子View沒(méi)有重寫onTouchEvent方法的話(比如子View是常用的ImageView,TextView之類的)照棋,你的OnClickListener就會(huì)無(wú)效了资溃,因?yàn)槟J(rèn)的onTouchEvent在處理ACTION_MOVE的時(shí)候,會(huì)檢查event的坐標(biāo)是否已經(jīng)脫離了View的邊界范圍烈炭,如果在邊界范圍之外的話溶锭,pressed將會(huì)失效(認(rèn)為沒(méi)有被按下),當(dāng)ACTION_UP時(shí)符隙,如果pressed為false趴捅,就不會(huì)執(zhí)行PerformClick。

那難道沒(méi)有方法可以完美地做到了嗎霹疫?
在ViewGroup的dispatchTouchEvent方法中拱绑,雖然它是逆序的for,但是呢丽蝎,它把子View拿出來(lái)的時(shí)候猎拨,卻不是直接操作的mChildren數(shù)組,而是通過(guò)一個(gè)getAndVerifyPreorderedView方法來(lái)獲得屠阻,這個(gè)方法會(huì)把當(dāng)前索引傳進(jìn)去红省,還有一個(gè)preorderedList。如果傳進(jìn)去的preorderedList不為空栏笆,那么就會(huì)直接從它里面去取类腮。

preorderedList怎么來(lái)?
通過(guò)調(diào)用buildOrderedChildList方法獲取的蛉加。

buildOrderedChildList方法是怎么樣的蚜枢?
它里面是通過(guò)一個(gè)getAndVerifyPreorderedIndex方法來(lái)獲取對(duì)應(yīng)的子View索引缸逃,這個(gè)方法要傳進(jìn)去一個(gè)叫customOrder的boolean值。這個(gè)customOrder厂抽,看名字可以知道需频,是自定義順序的意思,如果它為true的話筷凤,接著會(huì)通過(guò)getChildDrawingOrder(int childCount, int i)方法來(lái)獲取對(duì)應(yīng)的索引昭殉,而且,這個(gè)方法是protected的藐守,所以我們可以通過(guò)重寫這個(gè)方法并根據(jù)參數(shù)"i"來(lái)決定返回哪一個(gè)View所對(duì)應(yīng)的索引挪丢,從而改變分發(fā)的順序。

那這個(gè)customOrder卢厂,什么時(shí)候?yàn)閠rue呢乾蓬?
在buildOrderedChildList方法里可以看到這么一句:

final boolean customOrder = isChildrenDrawingOrderEnabled();

emmmm,也就是說(shuō)慎恒,如果要自定義這個(gè)順序的話任内,還需要調(diào)用setChildrenDrawingOrderEnabled(true)來(lái)開(kāi)啟。

重新捋一捋流程

  1. setChildrenDrawingOrderEnabled(true)來(lái)開(kāi)啟自定義順序
  2. 重寫getChildDrawingOrder方法來(lái)決定什么時(shí)候要返回哪個(gè)子View

使用場(chǎng)景

常用的SwipeRefreshLayout融柬、ViewPager死嗦、RecyclerView都實(shí)現(xiàn)getChildDrawingOrder方法。其中RecyclerView還可以通過(guò)一個(gè)setChildDrawingOrderCallback方法來(lái)動(dòng)態(tài)指定順序粒氧,而不用重寫RecyclerView越除。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市外盯,隨后出現(xiàn)的幾起案子廊敌,更是在濱河造成了極大的恐慌,老刑警劉巖门怪,帶你破解...
    沈念sama閱讀 221,820評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件骡澈,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡掷空,警方通過(guò)查閱死者的電腦和手機(jī)肋殴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)坦弟,“玉大人护锤,你說(shuō)我怎么就攤上這事∧鸢” “怎么了烙懦?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,324評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)赤炒。 經(jīng)常有香客問(wèn)我氯析,道長(zhǎng)亏较,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,714評(píng)論 1 297
  • 正文 為了忘掉前任掩缓,我火速辦了婚禮雪情,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘你辣。我一直安慰自己巡通,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布舍哄。 她就那樣靜靜地躺著宴凉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪表悬。 梳的紋絲不亂的頭發(fā)上跪解,一...
    開(kāi)封第一講書(shū)人閱讀 52,328評(píng)論 1 310
  • 那天,我揣著相機(jī)與錄音签孔,去河邊找鬼。 笑死窘行,一個(gè)胖子當(dāng)著我的面吹牛饥追,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播罐盔,決...
    沈念sama閱讀 40,897評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼但绕,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了惶看?” 一聲冷哼從身側(cè)響起捏顺,我...
    開(kāi)封第一講書(shū)人閱讀 39,804評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎纬黎,沒(méi)想到半個(gè)月后幅骄,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,345評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡本今,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評(píng)論 3 340
  • 正文 我和宋清朗相戀三年拆座,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片冠息。...
    茶點(diǎn)故事閱讀 40,561評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡挪凑,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出逛艰,到底是詐尸還是另有隱情躏碳,我是刑警寧澤,帶...
    沈念sama閱讀 36,238評(píng)論 5 350
  • 正文 年R本政府宣布散怖,位于F島的核電站菇绵,受9級(jí)特大地震影響肄渗,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜脸甘,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評(píng)論 3 334
  • 文/蒙蒙 一恳啥、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧丹诀,春花似錦钝的、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,417評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至枚荣,卻和暖如春碗脊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背橄妆。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,528評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工衙伶, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人害碾。 一個(gè)月前我還...
    沈念sama閱讀 48,983評(píng)論 3 376
  • 正文 我出身青樓矢劲,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親慌随。 傳聞我的和親對(duì)象是個(gè)殘疾皇子芬沉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容