【问题标题】:DialogFragment disappears on rotation despite setRetainInstance(true)尽管 setRetainInstance(true),DialogFragment 在旋转时消失
【发布时间】:2013-09-23 16:18:37
【问题描述】:

我有一个使用 android-support-v4 片段 API 的“hello world”样示例应用程序。 该活动由一个按钮组成,单击它将显示一个DialogFragment。 但是,旋转等配置更改会导致对话框消失,即使使用了 setRetainInstance(true)。

知道如何解决这个问题吗?

RetFragment.java

package me.local.HelloFroyo;

import android.os.Bundle;
import android.support.v4.app.*;
import android.util.Log;
import android.view.*;

public class RetFragment extends DialogFragment {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        return inflater.inflate(R.layout.hello_dialog_fragment, container);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e("RET", "onDestroy");
    }
}

MainActivity.java

package me.local.HelloFroyo;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.View;

public class MainActivity extends FragmentActivity {

    private static final String TAG_DLG = "myFragDlg";

    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        this.setContentView(R.layout.activity_main);
    }

    public void onShowClick(View v) {
        RetFragment ret = new RetFragment();
        ret.show(getSupportFragmentManager(), TAG_DLG);
    }
}

【问题讨论】:

    标签: android


    【解决方案1】:

    只是对此发表评论:

    “即使使用了 setRetainInstance(true)。”

    这不是“即使”,而是“因为它”。如果 setRetainInstance 为 false,对话框旋转就好了。

    这是我在这里找到的解决方法,对我来说效果很好:http://code.google.com/p/android/issues/detail?id=17423

    @Override
    public void onDestroyView()
    {
        Dialog dialog = getDialog();
    
        // Work around bug: http://code.google.com/p/android/issues/detail?id=17423
        if ((dialog != null) && getRetainInstance())
            dialog.setDismissMessage(null);
    
        super.onDestroyView();
    }
    

    【讨论】:

    • @ch3rryc0ke 你找到解决办法了吗,我也有同样的问题。我已经实现了上面的代码,但对话框仍然被关闭
    • 我不确定这里的解决方法,但你是对的,在这种情况下你不应该使用setRetainInstance。如果您想保留某个状态,请使用savedInstanceState 或arguments Bundle。 Android 文档中有一个good example,介绍了如何最好地使用DialogFragment 生成AlertDialogs。
    • 基于此:stackoverflow.com/a/11318942/1041533 我会说如果 setRetainInstance 设置为 true,则整个片段的状态都会保持(除了它的视图 - 需要重新创建的视图)。所以你说的整个 Fragment 被重新创建是因为 setRetainInstance(true) 似乎不太正确,而是相反的情况?
    【解决方案2】:

    DialogFragments 可以自行承受旋转变化,您不需要 setRetainInstance

    但是,如果你设置它,这是一个可重现的错误,使用 setRetainInstance(true) 和 DialogFragments

    http://code.google.com/p/android/issues/detail?id=17423&q=setRetaininstance&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars

    只是不要设置保留实例,你的对话框会正常工作

    但是,如果您的 DialogFragment 中有一个 AsyncTask 正在运行,并且您希望将其持久化,请使用带有 AsyncTaskLoader 的 LoaderManager。它也可以在配置更改后继续存在

    【讨论】:

      【解决方案3】:

      对于那些即使在setRetainInstance(true) 或覆盖onDestroyView 之后仍然无法正常工作的人,请确保在覆盖onSaveInstanceState 时调用super.onSaveInstanceState():

      @Override
      protected void onSaveInstanceState(Bundle outState) {
          super.onSaveInstanceState(outState); // <-- must call this if you want to retain dialogFragment upon rotation
          ...
      }
      

      即使没有 setRetainInstance 或覆盖 onDestroyView,dialogFragment 也应该在旋转时自行处理对话重新创建。

      【讨论】:

        【解决方案4】:

        尝试添加

        android:configChanges="orientation"
        

        在 AndroidManifest 文件中与您的活动相关。

        【讨论】:

        • 我不想阻止整个活动被销毁和重新创建,我只想保留 DialogFragment。
        • 这不会再次创建您的活动。如果您将其添加到您的活动中,它将保持相同的状态。如果没有此声明,您的活动就会在您每次更改方向时创建。
        • 我知道,但我只想保留对话片段。该活动应该被销毁并重新创建。您熟悉片段 API 吗?
        • 我刚刚注意到文档中提到 setRetainInstance(true) 仅适用于不在后台堆栈上的片段。我在setRetainInstance(true)前面加了getFragmentManager.popBackStack(),现在可以了。
        • 更正:这毕竟不能正常工作。 :(实际上片段仍然被销毁并重新创建,但是对话框在旋转后显示。但是,这不是我需要的100%。对话框实例应该被保留。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多