为什么不分段保留状态时,屏幕旋转? [英] Why won't Fragment retain state when screen is rotated?

查看:119
本文介绍了为什么不分段保留状态时,屏幕旋转?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经有一些麻烦内的preferenceFragment一些自定义对话框preference子类,以保持可见当屏幕旋转。我使用的是preferenceActivity时,不会遇到这个问题,所以我不知道它是否是一个Android错误或与我的code的一个问题,但我想有人来确认它们是否具有相同经验。

I've been having some trouble getting some custom DialogPreference subclasses inside a PreferenceFragment to remain visible when the screen is rotated. I don't experience this problem when using a PreferenceActivity, so I don't know whether it's an Android bug or a problem with my code, but I'd like someone to confirm whether they are having the same experience.

要测试这一点,首先创建一个包含至少一个对话框preference一个preference屏幕(这并不重要子类)。然后在preferenceActivity显示。当您在对话框preference运行你的应用程序,preSS所以它的对话节目。然后旋转屏幕,这样的方向变化。请问该对话框保持可见?

To test this, first create a preference screen containing at least one DialogPreference (it doesn't matter which subclass). Then display it in a PreferenceActivity. When you run your app, press on the DialogPreference so that it's dialog shows. Then rotate the screen so the orientation changes. Does the dialog remain visible?

然后尝试相同,但有一个preferenceFragment,以显示你的preferences而不是preferenceActivity。再次,不对话框保持可见,当你旋转屏幕?

Then try the same, but with a PreferenceFragment to display your preferences instead of a PreferenceActivity. Again, does the dialog remain visible when you rotate the screen?

到目前为止,我发现,如果使用preferenceActivity对话框将仍然可见,但如果使用preferenceFragment。纵观<一href="https://github.com/android/platform_frameworks_base/blob/master/core/java/android/$p$pference/Dialog$p$pference.java">source code的对话框preference ,似乎是正确的行为是为对话框保持可见,因为 isDialogShowing 是获得国家信息保存时的onSaveInstanceState()被称为在屏幕上重新定位。因此,我认为一个bug可能是preventing的preferenceFragment(和一切在里面),从恢复的状态信息。

So far, I've found that the dialog will remain visible if using a PreferenceActivity, but not if using a PreferenceFragment. Looking at the source code for DialogPreference, it seems that the correct behaviour is for the dialog to remain visible, because isDialogShowing is the state information that gets saved when onSaveInstanceState() is called on screen re-orientation. Therefore, I think a bug may be preventing the PreferenceFragment (and everything inside it) from restoring that state information.

如果这是一个Android的错误,那么它具有深远的意义,因为任何人都使用preferenceFragment无法保存和恢复状态的信息。

If it is an Android bug, then it has far-reaching implications, because anyone using PreferenceFragment cannot save and restore state information.

有人可以证实?如果它不是一个错误,那么这是怎么回事?

Can someone please confirm? If it's not a bug, then what is going on?

推荐答案

终于想出了一个解决这个问题。原来,这是不是一个错误,而是一个问题/监督的Andr​​oid开发者文档。

Finally figured out a solution to this problem. Turns out it's not a bug, but a problem/oversight in the Android developer documentation.

您看,我在这里以下的preferenceFragment教程。这篇文章告诉你做到以下几点,以实例化活动中的preferenceFragment:

You see, I was following the PreferenceFragment tutorial here. That article tells you to do the following in order to instantiate your PreferenceFragment within an Activity:

public class SettingsActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Display the fragment as the main content.
        getFragmentManager().beginTransaction()
                .replace(android.R.id.content, new SettingsFragment())
                .commit();
    }
} 

这样做的问题是,当您更改屏幕方向(或破坏并重新创建活动的任何其他操作),您的preferenceFragment将获得创建两次,这是什么导致它失去了它的状态。

The problem with this is that when you change the screen orientation (or any other action that destroys and re-creates the Activity), your PreferenceFragment will get created twice, which is what causes it to lose its state.

首先通过创建活动的通话将发生 super.onCreate()(如上图所示),这将调用 onActivityCreated()方法为您的preferenceFragment()和 onRestoreInstanceState()方法,为每个preference它包含的内容。这将成功地还原一切的状态。

The first creation will occur via the Activity's call to super.onCreate() (shown above), which will call the onActivityCreated() method for your PreferenceFragment () and the onRestoreInstanceState() method for each Preference it contains. These will successfully restore the state of everything.

但后来一旦调用 super.onCreate()的回报,你可以看到的onCreate()方法然后继续创建preferenceFragment一个第二的时间。因为它是毫无意义的再创造(而这一次,没有状态信息!),所有这些只是成功恢复的状态将被彻底丢弃/丢失。这就解释了为什么一个对话框preference可表示在该活动被破坏将不再是一旦活动可见的时间是重新创建

But then once that call to super.onCreate() returns, you can see that the onCreate() method will then go on to create the PreferenceFragment a second time. Because it is pointlessly created again (and this time, without state information!), all of the state that was just successfully restored will be completely discarded/lost. This explains why a DialogPreference that may be showing at the time that the Activity is destroyed will no longer be visible once the Activity is re-created.

那么,有什么解决办法?好了,只需添加一个小的检查,以确定是否为preferenceFragment已经创建,像这样:

So what's the solution? Well, just add a small check to determine whether the PreferenceFragment has already been created, like so:

public class SettingsActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Fragment existingFragment = getFragmentManager().findFragmentById(android.R.id.content);
        if (existingFragment == null || !existingFragment.getClass().equals(SettingsFragment.class))
        {
            // Display the fragment as the main content.
            getFragmentManager().beginTransaction()
                .replace(android.R.id.content, new SettingsFragment())
                .commit();
        }
    }
}

或者另一种方式是简单地检查的onCreate()是为了恢复状态而定,像这样:

Or another way is to simply check if onCreate() is meant to restore state or not, like so:

public class SettingsActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (savedInstanceState == null)
        {
            // Display the fragment as the main content.
            getFragmentManager().beginTransaction()
                .replace(android.R.id.content, new SettingsFragment())
                .commit();
        }
    }
}

所以我想在这里学到的教训是,的onCreate()具有双重作用 - 它可以建立一个活动的第一次,也可以从一个恢复以前的状态。

So I guess the lesson learnt here is that onCreate() has a dual role - it can set up an Activity for the first time, or it can restore from an earlier state.

这里的答案 使我实现这个解决方案。

The answer here led me to realizing this solution.

这篇关于为什么不分段保留状态时,屏幕旋转?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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