在Activity#onResume()上显示DialogFragment的正确方法

时间:2014-06-17 14:29:41

标签: android android-fragments android-dialogfragment

每次用户输入DialogFragment时,我都需要显示Activity,因此最佳回调方法为onResume()。事情是我无法致电DialogFragment#show(),因为它会抛出一些IllegalStateException,所以我这样做了:

@Override
protected void onResume() {
    super.onResume();

    if(!dialog.isVisible()) {
        dialog.show(getSupportFragmentManager(), "login-dialog");
    }
}

@Override
protected void onPause() {
    super.onPause();

    if(dialog.isVisible()) {
        dialog.dismiss();
    }
}

我得到了:

java.lang.IllegalStateException: Fragment already added: LoginDialog{41fac3e0 #0 login-dialog}

2 个答案:

答案 0 :(得分:2)

在尝试保持DialogFragment可见并在屏幕旋转(方向更改)之间工作时,我有完全相同的异常和消息。 您的片段来自支持库吗?

在我的情况下,我使用的是支持库,而dialog.show()的调用位于活动的onCreate()中。似乎解决了这个问题的是这里提出的解决方法:

https://stackoverflow.com/a/14016339/3577211

这主要是将setRetainInstance(true)放入DialogFragment onCreate()。第二部分,即覆盖其onDestroy,是我设法使DialogFragment在屏幕旋转期间不会消失(并在再次旋转时返回)的唯一方法,即使他们说最新的支持库版本照顾好了(也许我在这里混乱了罐子。)

您没有说明是否始终获得异常,或者仅在第一次创建活动时才起作用。但我猜测正在发生的事情是dialog.show()实际上是getFragmentManager().add()调用的包装器,它可能会检查setRetainInstancetrue是否为dialog false如果是DialogFragmentFragmentManager实例将再次添加到同一onResume()实例,这会抛出该异常。

另一个建议是不要使用onCreate();而是使用带有某种标志的onSaveInstanceState(Bundle outState)dialog,因为这样你可以跨活动周期保存数据(除非你的onResume()只是一个弹出常量消息,这对于每次用户点击{{1}}时,您可能会有一些与用户交互的数据,这些数据可能会在意外情况下丢失。)

答案 1 :(得分:0)

变化 !dialog.isVisible() 至 !dialog.isAdded()