在应用程序处于后台时解除DialogFragment的正确方法

时间:2012-02-17 08:46:47

标签: android android-fragments android-dialog android-dialogfragment

我开始使用DialogFragment,因为他们通过方向更改和内容很好地工作。但是我遇到了一个令人讨厌的问题。

我有AsyncTask显示进度DialogFragment并将其解除onPostExecute。一切正常,除非在应用程序处于后台时发生onPostExecute(例如,在按下Home按钮后)。然后我在DialogFragment解雇时遇到了这个错误 - “Can not perform this action after onSaveInstanceState”。卫生署。常规对话框工作得很好。但不是FragmentDialog。

所以我想知道,在应用程序处于后台时,解雇DialogFragment的正确方法是什么?我并没有真正使用Fragments,所以我认为我只是缺少一些东西。

5 个答案:

答案 0 :(得分:128)

DialogFragment有一个名为dismissAllowingStateLoss()

的方法

答案 1 :(得分:11)

这就是我所做的(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)...

答案 2 :(得分:3)

这是我为实现你想要的目标而必须做的事情: 我有一个Fragment活动,我在其上显示了一个名为JSONObject jsonObj = new JSONObject(jsonStr); JSONArray hits = jsonObj.getJSONArray("hits"); for (int i = 0; i < hits.length(); i++) { JSONObject h = hits.getJSONObject(i); JSONObject recipe = h.getJSONObject("recipe"); String Uri = recipe.getString("uri"); String Label = recipe.getString("label"); String Image = recipe.getString("image"); HashMap<String, String> recipe_ = new HashMap<>(); recipe_.put("uri", Uri); recipe_.put("label", Label); recipe_.put("image", Image); recipeList.add(recipe_); 的对话框片段,该片段在顶部全局声明。如果在活动进入后台并且返回前台之前显示fragment_RedemptionPayment,则以下代码将解除DialogFragment

     @Override
        public void onResume() {
            super.onResume();        
            if(fragment_RedemptionPayment.isVisible()){
                fragment_RedemptionPayment.dismiss();
            }
}

答案 3 :(得分:0)

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

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

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

答案 4 :(得分:0)

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

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

以这种方式检查其状态是否已保存,基本上是暂停并已调用onSaveInstanceState

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