Android - 如何在 onPause 中关闭所有对话框

问题描述 投票:0回答:6

我有一个活动可以在运行时显示不同的对话框。我使用 onCreateDialog(int id) 创建每个对话框,并使用 showDialog(int id) 和 DismissDialog(int id) 方法分别显示和关闭每个对话框。

当调用 onPause() 时,我不知道正在显示哪个对话框(如果有)。我想确保当调用 onPause 时,所有对话框都被关闭。是否有推荐的方法来消除所有对话框?我是否必须为每个对话框调用dismissDialog()?

android dialog
6个回答
51
投票

如果您正在使用 DialogFragment 并且您想关闭所有可以使用的内容:

/**
 * Dismiss all DialogFragments added to given FragmentManager and child fragments
 */
public static void dismissAllDialogs(FragmentManager manager) {
    List<Fragment> fragments = manager.getFragments();

    if (fragments == null)
        return;

    for (Fragment fragment : fragments) {
        if (fragment instanceof DialogFragment) {
            DialogFragment dialogFragment = (DialogFragment) fragment;
            dialogFragment.dismissAllowingStateLoss();
        }

        FragmentManager childFragmentManager = fragment.getChildFragmentManager();
        if (childFragmentManager != null)
            dismissAllDialogs(childFragmentManager);
    }
}

Kotlin 版本:

fun FragmentManager.dismissAllDialogs() {
    fragments.forEach { fragment ->
        (fragment as? DialogFragment)?.dismissAllowingStateLoss()
        fragment.childFragmentManager.dismissAllDialogs()
    }
}

17
投票

取决于我们讨论的对话数量。简短的答案是肯定的,您必须关闭每个对话框。

除了简单地在活动级别声明一些对话框之外,可能还有其他优雅的方法可以做到这一点。一旦声明了所有对话框,您就可以将它们存储在 HashMap 中,然后迭代列表并在 onPause 时关闭每个对话框。

由于您不知道哪些状态是开放的,因此您需要仔细检查并测试或跟踪状态。

但是,如果您的屏幕上确实有这么多对话框,您的 UI/UX 设计可能会遇到一些问题,因为 Android 应该为您提供一个模型,使您可以轻松实现它,而不会出现看起来很糟糕的设计。


8
投票

随着 Android 最近强调使用 DialogFragment 容器,您不需要对每个

调用解雇

由于对话框将有一个片段容器,您可以简单地使用它们的生命周期。考虑这个 DialogFragment:

public class FragDialog extends DialogFragment{

    public ProgressDialog _dialog;

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        if (savedInstanceState != null) {
            //this.dismiss();     <-- The dialogs may be dismissed here
        }
    }

    @Override
    public Dialog onCreateDialog(final Bundle savedInstanceState) {

        _dialog = new ProgressDialog(getActivity());
        return _dialog;
    }

    @Override
    public void onPause() {
        super.onPause();
        // <--------- You may overload onPause
    }
}

您将使用fragmentmanager在您的活动中显示它,通常这样调用它:

FragmentManager fm = getSupportFragmentManager();
FragDialog fragDialog = new FragDialog();
fragDialog.show(fm, "my_tag");

请注意,您实际上可以更改 DialogFragment 在 onPause 中执行的操作。当你的activity调用onPause时,这个onPause也会被调用。

使用 this.dismiss() 在 onPause() 中关闭对话框不会完成工作,因为一旦活动恢复,它也会恢复对话框。 (我认为这是因为 savestate 是在 onPause 之前存储的)。

但是,如果您检测到代码中所示的保存实例状态(简历),则可以安全地关闭 onCreate 中的对话框。


4
投票

在 Kotlin 中你可以让它变得更容易。

如果您想关闭所有 DialogFragment:

    private fun dismissDialogs() {
        supportFragmentManager.fragments.takeIf { it.isNotEmpty() }
                ?.map { (it as? DialogFragment)?.dismiss() }
    }

如果您想关闭除一个之外的所有 DialogFragment:

    private fun dismissDialogs(fragment: DialogFragment) {
        supportFragmentManager.fragments.takeIf { it.isNotEmpty() }
                ?.map { if (it != fragment) (it as? DialogFragment)?.dismiss() }
    }

3
投票

我有一个不同的解决方案,这可能很好。您只需将自定义对话框扩展为此

SiblingDialog
,它将为您的
Dialog
订阅关闭对话框的广播事件。因此,您可以将广播事件发送到任何您想要的地方,并且所有
SiblingDialogs
将被关闭。

在此示例中,取消和关闭对话框方法已被覆盖,因此

SiblingDialog
本身会在关闭时关闭所有其他同级。

public class SiblingDialog extends Dialog {

    protected LocalBroadcastManager mLocalBroadcastManager;

    protected BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            switch (intent.getAction()) {
                case "CLOSE_ALL_DIALOGS":
                    if (isShowing()) {
                        dismiss();
                    }
                    break;
                default:
                    break;
            }
        }
    };
    String[] ACTIONS_LIST = {"CLOSE_ALL_DIALOGS"};

    public SiblingDialog(Context context) {
        super(context);
    }

    public SiblingDialog(Context context, int themeResId) {
        super(context, themeResId);
    }


    public SiblingDialog(Context context, boolean cancelable, OnCancelListener cancelListener) {
        super(context, cancelable, cancelListener);
    }

    private void registerTheBroadCast() {
        mLocalBroadcastManager = LocalBroadcastManager.getInstance(getContext());
        IntentFilter mIntentFilter = new IntentFilter();
        for (String actions : ACTIONS_LIST) {
            mIntentFilter.addAction(actions);
        }
        mLocalBroadcastManager.registerReceiver(mBroadcastReceiver, mIntentFilter);
    }

    private void unregisterBroadCast() {
        mLocalBroadcastManager.unregisterReceiver(mBroadcastReceiver);
    }

    @Override
    public void show() {
        registerTheBroadCast();
        super.show();
    }

    @Override
    public void cancel() {
        unregisterBroadCast();
        mLocalBroadcastManager.sendBroadcast(newIntent("CLOSE_ALL_DIALOGS"));
        super.cancel();

    }

    @Override
    public void dismiss() {
        unregisterBroadCast();
        mLocalBroadcastManager.sendBroadcast(new Intent("CLOSE_ALL_DIALOGS"));
        super.dismiss();
    }
}

0
投票

**

public static void dismissAllDialogs(FragmentManager manager) {
        List<Fragment> fragments = manager.getFragments();
        if (fragments == null)
            return;
        for (Fragment fragment : fragments) {
            if (fragment instanceof DialogFragment) {
                DialogFragment dialogFragment = (DialogFragment) fragment;
                dialogFragment.dismiss();
            }
        }
    }

**

© www.soinside.com 2019 - 2024. All rights reserved.