如何通过旋转正确保留 DialogFragment? [英] How to properly retain a DialogFragment through rotation?

查看:25
本文介绍了如何通过旋转正确保留 DialogFragment?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个承载 DialogFragment 的 FragmentActivity.

I have a FragmentActivity that hosts a DialogFragment.

DialogFragment 执行网络请求并处理 Facebook 身份验证,因此我需要在轮换期间保留它.

The DialogFragment perform network requests and handles Facebook authentication, so I need to retain it during rotation.

我已阅读与此问题相关的所有其他问题,但没有一个真正解决了该问题.

I've read all the other questions relating to this issue, but none of them have actually solved the problem.

我正在使用 putFragment 和 getFragment 来保存 Fragment 实例并在重新创建活动时再次获取它.

I'm using putFragment and getFragment to save the Fragment instance and get it again during activity re-creation.

但是,我总是在调用 onRestoreInstanceState 中的 getFragment 时遇到空指针异常.我还想防止对话框在轮换期间被关闭,但到目前为止我什至无法保留它的实例.

However, I'm always getting a null pointer exception on the call to getFragment in onRestoreInstanceState. I would also like to keep the dialog from being dismissed during rotation, but so far I can't even retain the instance of it.

知道出了什么问题吗?

这是我的代码目前的样子:

Here's what my code currently looks like:

public class OKLoginActivity extends FragmentActivity implements OKLoginDialogListener
{

    private OKLoginFragment loginDialog;
    private static final String TAG_LOGINFRAGMENT = "OKLoginFragment";


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

        FragmentManager fm = getSupportFragmentManager();

        if(savedInstanceState == null)
        {
            loginDialog = new OKLoginFragment(); 
            loginDialog.show(fm, TAG_LOGINFRAGMENT);
        }
    }


    @Override
    public void onSaveInstanceState(Bundle outState)
    {
        getSupportFragmentManager().putFragment(outState,TAG_LOGINFRAGMENT, loginDialog);
    }

    @Override
    public void onRestoreInstanceState(Bundle inState)
    {
        FragmentManager fm = getSupportFragmentManager();
        loginDialog = (OKLoginFragment) fm.getFragment(inState, TAG_LOGINFRAGMENT);
    }

}

这是异常堆栈跟踪:

02-01 16:31:13.684: E/AndroidRuntime(9739): FATAL EXCEPTION: main
02-01 16:31:13.684: E/AndroidRuntime(9739): java.lang.RuntimeException: Unable to start activity ComponentInfo{io.openkit.example.sampleokapp/io.openkit.OKLoginActivity}: java.lang.NullPointerException
02-01 16:31:13.684: E/AndroidRuntime(9739):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
02-01 16:31:13.684: E/AndroidRuntime(9739):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
02-01 16:31:13.684: E/AndroidRuntime(9739):     at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3692)
02-01 16:31:13.684: E/AndroidRuntime(9739):     at android.app.ActivityThread.access$700(ActivityThread.java:141)
02-01 16:31:13.684: E/AndroidRuntime(9739):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1240)
02-01 16:31:13.684: E/AndroidRuntime(9739):     at android.os.Handler.dispatchMessage(Handler.java:99)
02-01 16:31:13.684: E/AndroidRuntime(9739):     at android.os.Looper.loop(Looper.java:137)
02-01 16:31:13.684: E/AndroidRuntime(9739):     at android.app.ActivityThread.main(ActivityThread.java:5039)
02-01 16:31:13.684: E/AndroidRuntime(9739):     at java.lang.reflect.Method.invokeNative(Native Method)
02-01 16:31:13.684: E/AndroidRuntime(9739):     at java.lang.reflect.Method.invoke(Method.java:511)
02-01 16:31:13.684: E/AndroidRuntime(9739):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
02-01 16:31:13.684: E/AndroidRuntime(9739):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
02-01 16:31:13.684: E/AndroidRuntime(9739):     at dalvik.system.NativeStart.main(Native Method)
02-01 16:31:13.684: E/AndroidRuntime(9739): Caused by: java.lang.NullPointerException
02-01 16:31:13.684: E/AndroidRuntime(9739):     at android.support.v4.app.FragmentManagerImpl.getFragment(FragmentManager.java:528)
02-01 16:31:13.684: E/AndroidRuntime(9739):     at io.openkit.OKLoginActivity.onRestoreInstanceState(OKLoginActivity.java:62)
02-01 16:31:13.684: E/AndroidRuntime(9739):     at android.app.Activity.performRestoreInstanceState(Activity.java:910)
02-01 16:31:13.684: E/AndroidRuntime(9739):     at android.app.Instrumentation.callActivityOnRestoreInstanceState(Instrumentation.java:1131)
02-01 16:31:13.684: E/AndroidRuntime(9739):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2158)

推荐答案

在你的 DialogFragment 中,调用 Fragment.setRetainInstance(boolean),值为 true.您不需要手动保存片段,框架已经处理了所有这些.调用此方法将防止您的片段在轮换时被破坏,您的网络请求将不受影响.

Inside your DialogFragment, call Fragment.setRetainInstance(boolean) with the value true. You don't need to save the fragment manually, the framework already takes care of all of this. Calling this will prevent your fragment from being destroyed on rotation and your network requests will be unaffected.

由于 bug 兼容库:

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

这篇关于如何通过旋转正确保留 DialogFragment?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆