問題:在使用dialogFragment的時(shí)候?qū)τ诜祷劓I的處理出現(xiàn)一些問題宋税,需求如下:1.如果有鍵盤彈出的時(shí)候點(diǎn)擊返回鍵,鍵盤收起讼油,DialogFragment不關(guān)閉杰赛。
2.如果沒有鍵盤彈出 作出一些操作,并同時(shí)關(guān)閉當(dāng)前DialogFragment和Activity矮台。
如果不對(duì)返回鍵事件進(jìn)行處理乏屯,在點(diǎn)擊返回鍵的時(shí)候首先會(huì)先關(guān)閉當(dāng)前DialogFragment根时,再次點(diǎn)擊才回關(guān)閉Activity。
如果設(shè)置了DialogFragment的setCancelable(false) 是不會(huì)關(guān)閉當(dāng)前的DialogFragment的辰晕,但是返回事件也不會(huì)傳給Activity蛤迎,導(dǎo)致關(guān)閉不掉Activity
這時(shí)候想到要對(duì)返回鍵做出處理,在DialogFragment的onKey中進(jìn)行事件捕獲含友,在onKeyUp的時(shí)候去判斷此次點(diǎn)擊是收起鍵盤替裆,還是要關(guān)閉DialogFragment和Activity。
那么問題來了窘问,如何判斷當(dāng)前軟鍵盤是否在顯示狀態(tài)辆童?返回鍵事件是否被軟鍵盤消費(fèi)掉了?
首先使用了一種方法? 通過根布局的onLayout來判斷軟鍵盤的顯示和收起南缓,在回調(diào)里做出標(biāo)識(shí)胸遇,來判斷當(dāng)前軟鍵盤是否在彈起狀態(tài)。
該方法可參見https://github.com/Jacksgong/JKeyboardPanelSwitch
然而汉形,事情不像想象的那么簡(jiǎn)單纸镊,onKeyUp的調(diào)用 和 從布局里判斷鍵盤的顯示隱藏并不是同步的,所以結(jié)果并不準(zhǔn)確概疆。這種方法被斃掉逗威。。
然后去看keyEvent事件的傳遞岔冀,在翻看WindowPhone的源碼凯旭,發(fā)現(xiàn)在有鍵盤彈出時(shí)候,dispatchKeyEvent會(huì)先處理軟鍵盤使套,并消費(fèi)掉這次事件罐呼。如下圖
所以想到 ,在點(diǎn)擊返回鍵時(shí)候 侦高,如果有鍵盤顯示嫉柴, DialogFragment的onKeyDown由于鍵盤已經(jīng)消費(fèi)掉事件是不會(huì)被調(diào)用的。只有onkeyUp在手指拿起的時(shí)候被調(diào)用 奉呛。
這時(shí)候可以設(shè)置一個(gè)標(biāo)識(shí)來標(biāo)識(shí)是否有鍵盤消費(fèi)了事件计螺。如果在onkeyup時(shí)候判斷標(biāo)志位未被改變 就說明是鍵盤消費(fèi)了事件,就不做出處理瞧壮。如果沒有鍵盤消費(fèi)事件登馒,onKeyDown會(huì)被調(diào)用,標(biāo)識(shí)會(huì)被改變咆槽,就可以繼續(xù)做出操作并關(guān)閉頁面了陈轿。如下圖
好了,到這里看起來是沒什么問題了,然而济欢,事情并沒有想象的那么簡(jiǎn)單赠堵。。
在真機(jī)測(cè)試時(shí)候發(fā)現(xiàn)? 有虛擬按鍵的手機(jī)在點(diǎn)擊返回鍵的時(shí)候會(huì)觸發(fā)一次onKeyDown(少量測(cè)試機(jī)測(cè)試法褥,不一定代表所有手機(jī)茫叭,畢竟android手機(jī)那么多。半等。)揍愁,有物理按鍵的手機(jī)在手指點(diǎn)擊返回鍵的時(shí)候會(huì)多次觸發(fā)onkeydown事件,這樣的話標(biāo)識(shí)是一定會(huì)被改變的杀饵。莽囤。就不能憑借這個(gè)變量來標(biāo)識(shí)是否是鍵盤消費(fèi)了返回事件。
好吧切距,通往成功的路是曲折的朽缎。。在就要絕望的時(shí)候想起了一句經(jīng)典的話谜悟,回家睡一覺话肖,明天早上來看一切都好了。葡幸。
最后研究 phonewindow中的dispatchKeyEvent
發(fā)現(xiàn)事件可以拿到事件重復(fù)次數(shù)的最筒,如果鍵盤消費(fèi)了事件 , 在dialogfragment的onkeyDown中獲取的重復(fù)次數(shù)是從1開始的蔚叨。如果沒有鍵盤消費(fèi)事件床蜘,獲取的重復(fù)次數(shù)是0。
也就是說 如果在onKeyDown中重復(fù)次數(shù)是0就說明返回事件沒有被鍵盤消費(fèi)掉蔑水, 可以認(rèn)為是這次點(diǎn)擊時(shí)是沒有鍵盤顯示的邢锯,這時(shí)候是可以直接在onKeyUp的時(shí)候把事件傳遞給activity進(jìn)行處理。如下圖:
final解決方案:
在dialogfragment 的onkey里面進(jìn)行判斷搀别,在onkeydown的時(shí)候判斷event.getRepeatCount() == 0? 如果是等于0的時(shí)候就說明是沒有處理鍵盤彈出事件丹擎,這種情況下 ,activity可以進(jìn)行操作后直接關(guān)閉 领曼。如果等于1 這時(shí)候說明是處理了鍵盤彈出事件 ,就不做處理
第一次寫蛮穿,有點(diǎn)亂糟糟的庶骄,沒看明白的不要吐槽我,有問題或者好的解決方案的可以給予指點(diǎn)践磅。单刁。