首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android 判斷 Dialog 是否處於最前端顯示狀態

     編輯:程式設計綜合問答

問題背景

應用顯示一個非 Activity 類型的 Dialog,當其他應用彈出(如來電、系統彈窗)遮蓋該 Dialog 時,需要檢測並做相應處理(如暫停動畫、釋放資源)。

解決方案:onWindowFocusChanged

Dialog 繼承自 Window,可通過重寫 onWindowFocusChanged(boolean hasFocus) 監聽焦點變化:

public class MyDialog extends Dialog {
    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (hasFocus) {
            // Dialog 獲得焦點,處於最前端可見狀態
            Log.d("Dialog", "顯示在最前端");
            // 恢復動畫、重新註冊傳感器等
        } else {
            // Dialog 失去焦點,被其他窗口遮蓋或最小化
            Log.d("Dialog", "被遮蓋/失去焦點");
            // 暫停動畫、釋放獨佔資源等
        }
    }
}

在 Activity 中監聽 Dialog 狀態

若不想自定義 Dialog 類,可在 Activity 中設置 OnDismissListener 和 OnCancelListener,但這無法檢測「被遮蓋但未消失」的狀態。

更精確的方案:WindowCallback

dialog.getWindow().setCallback(new Window.Callback() {
    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        // 同邏輯處理
    }
    // 其他回調方法需轉發給原 callback 或空實現
    @Override public boolean dispatchTouchEvent(MotionEvent event) { return false; }
    // ... 實現 Window.Callback 所有抽象方法
});

注意事項

  • onWindowFocusChanged 在 Dialog **顯示/隱藏**、**被系統彈窗遮蓋/恢復**、**按 Home 鍵切回/切出** 等場景均會觸發。
  • 無法區分「被彈窗遮蓋」與「用戶切換到其他 App」,兩者均表現為失去焦點。
  • 若需極精確控制(如僅在特定系統彈窗出現時暫停),需結合 WindowManager 類型判斷或無障礙服務,複雜度較高。

最佳實踐建議

  • 輕量級需求:重寫 Dialog 的 onWindowFocusChanged,處理焦點失去/獲得時的資源釋放/恢復。
  • 若 Dialog 承載關鍵業務(如支付、錄音),建議改用 **全屏 Activity (Theme.Dialog)**,利用 Activity 生命周期 onPause/onResume 更可靠地感知可見狀態。
  • 避免在焦點變化回調中執行耗時操作,保持 UI 流暢。

通過 onWindowFocusChanged 可滿足絕大多數「感知 Dialog 是否最前端可見」的業務場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved