Android - 如何解除onPause中的所有对话框

时间:2012-02-08 21:27:17

标签: android dialog

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

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

6 个答案:

答案 0 :(得分:23)

如果您正在使用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);
    }
}

答案 1 :(得分:14)

取决于我们谈论的对话框数量。简短的回答是肯定的,你必须解雇每个对话框。

除了在活动级别声明一些对话框之外,可能还有一些优雅的方法。您可以在声明后将所有对话框存储在HashMap中,然后遍历列表并关闭每个对话框onPause。

由于你不知道哪些是开放的,你需要经历并测试或跟踪状态。

但是,如果您在屏幕上真的有这么多对话框,那么您的UI / UX设计可能会遇到一些问题,因为Android应该为您提供一个模型,使其易于实现而不会出现设计不佳的情况。

答案 2 :(得分:8)

由于Android最近强调使用DialogFragment容器,你不需要在每个上调用

由于对话框将包含Fragment容器,因此您只需使用生命周期即可。考虑一下这个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中执行的操作。当您的活动调用onPause时,也会调用此onPause。

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

但如果您检测到代码中显示的savedInstanceState(简历),则可以安全地关闭onCreate中的对话框。

答案 3 :(得分:1)

在Kotlin中,您可以轻松得多。

如果您想关闭所有DialogFragments:

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

如果您要关闭除一个以外的所有DialogFragment:

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

答案 4 :(得分:0)

我有一个不同的解决方案,那可能很好。您只需将“自定义对话框”扩展名设置为此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();
    }
}

答案 5 :(得分:0)

**

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

**