如何检查当前活动是否有前面的对话框?

new*_*wme 18 android android-activity

我正在使用第三方库,有时会弹出一个对话框.在我完成当前活动之前,我想检查当前上下文中是否弹出了一个对话框.

这有什么API吗?

Alé*_*lho 15

您可以检查它是否在该活动的活动片段上运行,并检查其中一个是否为DialogFragment,这意味着屏幕上有一个活动对话框:

    public static boolean hasOpenedDialogs(FragmentActivity activity) {
        List<Fragment> fragments = activity.getSupportFragmentManager().getFragments();
        if (fragments != null) {
            for (Fragment fragment : fragments) {
                if (fragment instanceof DialogFragment) {
                    return true;
                }
            }
        }

        return false;
    }
Run Code Online (Sandbox Code Playgroud)

  • 被解雇的DialogFragment是否将从FragmentManager中删除 (2认同)

Jul*_*arz 12

我遇到了类似的问题,并且不想修改创建和显示对话框的所有位置.我的解决方案是通过该hasWindowFocus()方法查看我所显示的视图是否具有窗口焦点.这不适用于所有情况,但在我的特定情况下工作(这是在相当受限的情况下使用的内部录制应用程序).

这个解决方案没有经过彻底的稳健性测试,但我想我会发帖,以防它帮助了某些人.


Mad*_*han 8

AFAIK - 没有公共API.

建议的方法是引用对话框,并在必要时检查isShowing()并调用dismiss(),但由于您使用的是第三方库,因此这可能不适合您.

最好的办法是检查您使用的库的文档.如果这没有帮助,那你就不走运了.

提示:如果弹出一个对话框,活动将切换到"暂停"状态.你可能会'滥用'这种行为;)

  • 请注意,如果弹出一个对话框,活动不会切换为暂停,除非该对话框实际上是另一个样式为对话框的活动.请参见http://stackoverflow.com/a/7384782/25837 (4认同)

Oli*_*nas 8

这使用反射和隐藏API来获取当前活动的视图根.如果警报对话框显示这将返回其他视图根.但要小心,即使是一个toast popup也会返回一个额外的视图根.

我已经确认从Android 4.1到Android 6.0的兼容性,但当然这可能不适用于早期或更高版本的Android版本.

我没有检查多窗口模式的行为.

@SuppressWarnings("unchecked")
public static List<ViewParent> getViewRoots() {

    List<ViewParent> viewRoots = new ArrayList<>();

    try {
        Object windowManager;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            windowManager = Class.forName("android.view.WindowManagerGlobal")
                    .getMethod("getInstance").invoke(null);
        } else {
            Field f = Class.forName("android.view.WindowManagerImpl")
                    .getDeclaredField("sWindowManager");
            f.setAccessible(true);
            windowManager = f.get(null);
        }

        Field rootsField = windowManager.getClass().getDeclaredField("mRoots");
        rootsField.setAccessible(true);

        Field stoppedField = Class.forName("android.view.ViewRootImpl")
                .getDeclaredField("mStopped");
        stoppedField.setAccessible(true);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            List<ViewParent> viewParents = (List<ViewParent>) rootsField.get(windowManager);
            // Filter out inactive view roots
            for (ViewParent viewParent : viewParents) {
                boolean stopped = (boolean) stoppedField.get(viewParent);
                if (!stopped) {
                    viewRoots.add(viewParent);
                }
            }
        } else {
            ViewParent[] viewParents = (ViewParent[]) rootsField.get(windowManager);
            // Filter out inactive view roots
            for (ViewParent viewParent : viewParents) {
                boolean stopped = (boolean) stoppedField.get(viewParent);
                if (!stopped) {
                    viewRoots.add(viewParent);
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

    return viewRoots;
}
Run Code Online (Sandbox Code Playgroud)


Rev*_*ron 8

您可以覆盖活动方法onWindowFocusChanged(boolean hasFocus)并跟踪活动的状态。

通常,如果您的活动上方显示了一些警报对话框,则该活动不会获得onPause()onResume()事件。但是它会失去对显示的警报对话框的关注,并在它关闭时获得它。