77

我开始使用 DialogFragment,因为它们可以通过方向变化和其他东西很好地工作。但是我遇到了一个讨厌的问题。

我有AsyncTask显示进度 DialogFragment 并关闭它onPostExecute。一切正常,除非在onPostExecute应用程序处于后台时发生(例如,在按下主页按钮后)。然后我在 DialogFragment 关闭时收到此错误 - “ Can not perform this action after onSaveInstanceState”。多哈。常规对话框工作得很好。但不是 FragmentDialog。

所以我想知道,当应用程序在后台时关闭 DialogFragment 的正确方法是什么?我并没有真正使用过 Fragments,所以我认为我只是错过了一些东西。

4

5 回答 5

164

DialogFragment有一个方法叫做dismissAllowingStateLoss()

于 2012-04-23T05:03:46.073 回答
10

这就是我所做的(df == dialogFragment)

确保以这种方式调用对话框:

df.show(getFragmentManager(), "DialogFragment_FLAG");

当您想关闭对话框时,请进行以下检查:

if (df.isResumed()){
  df.dismiss();
}
return;

确保片段的 onResume() 方法中有以下内容(不是 df)

@Override
public void onResume(){
  Fragment f = getFragmentManager().findFragmentByTag("DialogFragment_FLAG");
  if (f != null) {
    DialogFragment df = (DialogFragment) f;
    df.dismiss();
  }
  super.onResume();
}   

这样,如果对话框可见,对话框将被关闭。如果不可见,对话框将在下一个片段变得可见时被关闭(onResume)......

于 2013-02-21T15:20:49.580 回答
3

这就是我必须做的事情来实现你想要的:我有一个片段活动,我正在显示一个名为的对话框片段fragment_RedemptionPayment,该片段在顶部全局声明。以下代码将取消DialogFragment它是否在活动进入后台并返回前台之前显示。

     @Override
        public void onResume() {
            super.onResume();        
            if(fragment_RedemptionPayment.isVisible()){
                fragment_RedemptionPayment.dismiss();
            }
}
于 2017-04-16T10:15:11.657 回答
2

在调用dismiss之前检查状态的另一种新方法是:

if(!dialog.isStateSaved){
    dialog.dismiss()
} else {
    //Change the UI to suit your functionality
}

通过这种方式检查状态是否保存,基本上是在暂停并onSaveInstanceState已被调用。

对于 Java,您可以使用isStateSaved()

于 2020-04-11T09:07:46.437 回答
0

一个可能有效的解决方案是Fragment.setRetainInstance(true)在您的对话片段中设置,但这不是最漂亮的修复。

有时我注意到我必须将我的对话操作排队以让框架首先恢复状态。如果您可以获取当前的 Looper(Activity.getMainLooper())并将其包装在 Handler 中,您可以尝试通过在该队列上发布一个可运行文件将您的解雇传递到队列的后面。

我经常最终使用一个单独的片段,它retaininstance(true)有一个ResultReceiver. 所以我将该结果接收器传递给我的工作并在其 onReceive 中处理回调(通常作为其他接收器的路由器)。但是,如果您使用异步任务,这可能比值得做的工作多一些。

于 2012-02-17T09:21:38.137 回答