標籤:activity 變數 call dispatch one 代碼 ros track 自己
在做自訂彈窗的時候遇到的問題,如果不繼承Dialog 或者popwindow 自己寫的通過 getWindow的decorView 給decorView view 動態添加View 和移除View實現彈窗會出現返回按鍵如果是彈窗情況下需要關閉彈窗(即移除View) ,那麼怎麼監聽返回按鍵?這裡看了dialog 和popwindow 發現了寫規律,即兩者都實現了Window.Callback,以及 KeyEvent.Callback, 這裡KeyEvent.Callback有三個實現方法:
onKeyUp :抬起
onKeyLongPress:長按
onKeyDown:按下
而Window.Callback,就比較多了,這裡我就不解釋了,主要說兩個地方:
dispatchKeyEvent :分發關鍵事件(這裡指的就是home鍵盤,或者返回鍵,以及音量鍵,電源鍵等這些是關鍵事件)
dispatchTouchEvent:分發觸摸事件,這裡是分發觸摸事件
如果想攔截手機的返回按鍵則需要在彈窗展示的時候讓視窗window 處理callback到這裡,
即window.setCallback( );是自己的這個回調,不然一直都是Activity在處理按鍵,以及觸摸事件
1.在show的時候activity.getWindow().setCallBack(this) 自己的實現
2.然後重寫 dispatchKeyEvent 讓處理分發
@Override public boolean dispatchKeyEvent(KeyEvent event) { if (xWindow.superDispatchKeyEvent(event)) { return true; } return event.dispatch(this, xWindow.getDecorView() != null ? xWindow.getDecorView().getKeyDispatcherState() : null, this); }
3.分發後就到了KeyEvent.CallBack的onKeyDown按下事件
@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { event.startTracking(); return true; } return false;}
4.按下事件處理過後就是抬起,這裡就判斷如果當前在展示,就關閉彈窗(移除View),然後消耗本次事件
@Overridepublic boolean onKeyUp(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && event.isTracking() && !event.isCanceled()) { if (isShowing) { dismiss(); return true; } return false; } return false;}
5.關閉彈窗後不要忘記把表單的回調還給Activity 的Callback
xWindow.setCallback(Activity);
6.到此為止關於按鍵就處理完了,但是還有問題,Callback不僅僅處理按鍵,還處理了觸摸事件,如果不做處理
那麼在螢幕觸就無效了,無論怎麼觸摸都沒響應,主要是因為
dispatchTouchEvent沒做處理,這裡還需要做處理:
@Overridepublic boolean dispatchTouchEvent(MotionEvent event) { if (xWindow.superDispatchTouchEvent(event)) { return true; } return false;}
到這裡位置就全部處理完畢了
上文中代碼 xWindow變數就是從Activity中gewindow()擷取到的window對象
安卓監聽觸摸事件,以及各種按鍵 處理