Xåp*_* - 27 android preferenceactivity android-preferences android-fragments dialog-preference
我在PreferenceFragment中获取一些自定义DialogPreference子类时遇到了一些麻烦,以便在旋转屏幕时保持可见.我在使用PreferenceActivity时没有遇到这个问题,因此我不知道它是Android错误还是代码问题,但我希望有人确认他们是否有相同的体验.
要对此进行测试,首先要创建一个包含至少一个DialogPreference的首选项屏幕(哪个子类无关紧要).然后在PreferenceActivity中显示它.运行应用程序时,请按DialogPreference以显示其对话框.然后旋转屏幕以使方向发生变化.对话框是否仍然可见?
然后尝试相同,但使用PreferenceFragment显示您的首选项而不是PreferenceActivity.再次,旋转屏幕时对话框是否仍然可见?
到目前为止,我发现如果使用PreferenceActivity,对话框将保持可见,但如果使用PreferenceFragment则不会.查看DialogPreference的源代码,似乎正确的行为是对话框保持可见,因为在屏幕isDialogShowing重定向时onSaveInstanceState()调用时会保存状态信息.因此,我认为一个错误可能会阻止PreferenceFragment(及其中的所有内容)恢复该状态信息.
如果它是Android错误,那么它具有深远的影响,因为任何使用PreferenceFragment的人都无法保存和恢复状态信息.
有人可以确认吗?如果它不是一个错误,那么发生了什么?
Xåp*_* - 52
最后找到了解决这个问题的方法.事实证明,这不是一个错误,而是Android开发人员文档中的问题/疏忽.
你看,我在这里关注PreferenceFragment教程.该文章告诉您要执行以下操作以在Activity中实例化PreferenceFragment:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
这样做的问题是,当您更改屏幕方向(或任何其他破坏并重新创建活动的操作)时,PreferenceFragment将被创建两次,这是导致它失去状态的原因.
第一次创建将通过Activity的调用super.onCreate()(如上所示)进行,该调用将调用onActivityCreated()PreferenceFragment()的onRestoreInstanceState()方法以及它包含的每个Preference 的方法.这些将成功恢复一切状态.
但是一旦调用super.onCreate()返回,您就可以看到该onCreate()方法将继续第二次创建PreferenceFragment .因为它是无意义地再次创建(这次,没有状态信息!),刚刚成功恢复的所有状态将被完全丢弃/丢失.这解释了为什么在重新创建活动后,可能在销毁活动时显示的DialogPreference将不再可见.
那么解决方案是什么?好吧,只需添加一个小的检查来确定是否已经创建了PreferenceFragment,如下所示:
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
或者另一种方法是简单地检查是否onCreate()意味着恢复状态,如下所示:
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
所以我想这里学到的经验教训是onCreate()双重角色 - 它可以首次设置一个Activity,也可以从之前的状态恢复.
这里的答案促使我实现了这个解决方案.
| 归档时间: |
|
| 查看次数: |
16529 次 |
| 最近记录: |