Android-如何取消onPause中的所有对话框

Android-如何取消onPause中的所有对话框,android,dialog,Android,Dialog,我有一个活动,可以在运行时显示不同的对话框。我使用onCreateDialog(int-id)创建每个对话框,并分别使用showDialog(int-id)和dismissDialog(int-id)方法show和dismissedialog 调用onPause()时,我不知道显示的是哪个对话框(如果有的话)。我想确保在调用onPause时,所有对话框都会缩小。是否有建议的方法关闭所有对话框?我是否需要为每个对话框调用dismissloal()?取决于我们讨论的对话框数量。简短的回答是肯定的,您

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


调用onPause()时,我不知道显示的是哪个对话框(如果有的话)。我想确保在调用onPause时,所有对话框都会缩小。是否有建议的方法关闭所有对话框?我是否需要为每个对话框调用dismissloal()?

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

除了在活动级别声明几个对话框之外,可能还有一些优雅的方法来实现这一点。声明完所有对话框后,可以将它们存储在HashMap中,然后遍历列表并在暂停时关闭每个对话框

因为你不知道哪些是开放的,你需要通过测试或跟踪状态


然而,如果你的屏幕上真的有这么多对话框,你的UI/UX设计可能会有一些问题,因为Android应该为你提供一个模型,使其易于实现,而不需要看起来很糟糕的设计。

随着Android最近强调使用容器,你不需要在每个对话框上都调用Dislose

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

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
    }
}
请注意,您实际上可能会更改DialogFragment在onPause中的操作。当您的活动调用onPause时,也将调用此onPause

使用此.dismise()在onPause()中取消对话框不会起作用,因为一旦活动恢复,它也会恢复对话框。(我认为这是因为savestate存储在onPause之前)


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

如果您正在使用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);
    }
}
/**
*关闭添加到给定FragmentManager和子片段的所有DialogFragments
*/
公共静态void dismissAllDialogs(碎片管理器){
List fragments=manager.getFragments();
if(片段==null)
返回;
for(片段:片段){
if(DialogFragment的片段实例){
DialogFragment=(DialogFragment)片段;
dialogFragment.dismissAllowingStateLoss();
}
FragmentManager childFragmentManager=fragment.getChildFragmentManager();
if(childFragmentManager!=null)
dismissAllDialogs(childFragmentManager);
}
}

我有一个不同的解决方案,这可能很好。您只将自定义对话框扩展设置为该
同级对话框
,它将订阅您的
对话框
,以广播关闭对话框的事件。因此,您可以将广播事件发送到任何您想要的地方,并且所有的
同级对话框
都将关闭

在本例中,取消和取消对话框方法已被覆盖,因此
同级对话框
本身在关闭时每隔一个同级关闭一次

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();
    }
}
**

publicstaticvoiddismissalldialogs(FragmentManager){
List fragments=manager.getFragments();
if(片段==null)
返回;
for(片段:片段){
if(DialogFragment的片段实例){
DialogFragment=(DialogFragment)片段;
dialogFragment.dismise();
}
}
}

**

在科特林,您可以让它变得更简单

如果您希望关闭所有DialogFragment:

    private fun dismissDialogs() {
        supportFragmentManager.fragments.takeIf { it.isNotEmpty() }
                ?.map { (it as? DialogFragment)?.dismiss() }
    }
如果要关闭除一个对话框外的所有对话框片段:

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

此外,为了避免由于关闭对话框而导致错误,每次关闭对话框时都可以使用try-catch。这比检查打开的对话框容易得多。看起来是DialogFragment迄今为止最干净的解决方案。您是否在生产应用程序中使用它?childFragmentManager为非空,因此check is not needGetFragments()将在必要时返回一个空列表,因此不需要null check这是一个简洁的解决方案,在2018年仍然有效,谢谢!很好的解决方案,谢谢
    private fun dismissDialogs() {
        supportFragmentManager.fragments.takeIf { it.isNotEmpty() }
                ?.map { (it as? DialogFragment)?.dismiss() }
    }
    private fun dismissDialogs(fragment: DialogFragment) {
        supportFragmentManager.fragments.takeIf { it.isNotEmpty() }
                ?.map { if (it != fragment) (it as? DialogFragment)?.dismiss() }
    }