我有一个活动可以在运行时显示不同的对话框。我使用onCreateDialog(int id)来创建每个对话框,我使用showDialog(int id)和dismissDialog(int id)方法分别显示和关闭每个对话框。
当调用onPause()时,我不知道正在显示哪个对话框(如果有)。我想确保在调用onPause时,所有对话框都会被忽略。是否有推荐的方法来解雇所有对话框?我是否必须为每个对话框调用dismissDialog()?
答案 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();
}
}
}
**