为什么我的 SwitchPreference 会在方向改变时出现故障?
Why does my SwitchPreference glitch on orientation change?
我有一个 activity(扩展 AppCompatActivity),其中包含 PreferenceFragment
和我的应用设置。第一个设置是用于启用或禁用通知的 SwitchPreference,然后是依赖于该 SwitchPreference 的其他首选项。
我的问题是:我发现如果我旋转设备(导致方向改变)然后点击开关,它不会正确呈现 - 它似乎显示两个重叠的开关(here's a screencap from a Moto X), one in the old position and one in the new position. Interestingly, this even happens with the older style of switches (here's a screencap from a Nexus S running JellyBean ).
我在互联网上没有发现任何关于此错误的信息,据我所知,它不会发生在 Android OS 应用程序(例如“设置”)或其他第三方应用程序(例如 Intrications Intent Intercept)。所以看来我只是在这里做错了什么。
这是我的 SettingsFragment 中的设置代码:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings);
// Grab Preference objects
final Preference wklyRemPref = findPreference(getString(R.string.prefkey_weekly_reminder));
// Set up notification settings
findPreference(getString(R.string.prefkey_allow_notifs))
.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (Boolean.FALSE.equals(newValue)) {
// Turn off and disable "Weekly Reminder" pref
((TwoStatePreference) wklyRemPref).setChecked(false);
// (Disabling is done by the system because the "Weekly Reminder"
// preference depends on the "Notifications" preference)
}
return true;
}
});
wklyRemPref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
Log.d("Pref", preference + " value changed (" + newValue + ")");
return true;
}
});
...
}
这是我的 settings.xml
文件:
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="Reminders">
<SwitchPreference
android:defaultValue="true"
android:key="@string/prefkey_allow_notifs"
android:title="@string/allow_notifs"/>
<!-- Weekly reminder: -->
<CheckBoxPreference
android:dependency="@string/prefkey_allow_notifs"
android:defaultValue="true"
android:key="@string/prefkey_weekly_reminder"
android:summary="Remind me weekly to choose a scripture"
android:title="Weekly reminder" />
<net.danmercer.ponderizer.settings.ReminderPreference
android:defaultValue="sunday/17:00"
android:dependency="@string/prefkey_weekly_reminder"
android:key="@string/prefkey_weekly_reminder_time"
android:title="Set weekly reminder time" />
<!-- Notification preferences -->
<RingtonePreference
android:dependency="@string/prefkey_allow_notifs"
android:key="@string/prefkey_notif_sound"
android:title="Notification Sound"
android:ringtoneType="notification"
android:showDefault="true"
android:showSilent="true"/>
<CheckBoxPreference
android:defaultValue="true"
android:dependency="@string/prefkey_allow_notifs"
android:key="@string/prefkey_notif_vibrate"
android:title="Vibrate" />
</PreferenceCategory>
...
</PreferenceScreen>
编辑:
我还尝试清理并重建我的项目,卸载并重新安装该应用程序,但无济于事。
编辑 2:
我尝试使用 CheckBoxPreference 而不是 SwitchPreference 并遇到了同样的问题。更糟糕的是,当我旋转 activity 时,我发现整个片段似乎都被烧进了屏幕(可以这么说)。我可以滚动设置片段,但它之前的样子仍然存在。这个神器早些时候表现为两个重叠的开关,但我没有意识到它如此普遍。
我发现了问题。在我的 SettingsActivity onCreate() 方法中,我有这样的代码:
FragmentManager fm = getFragmentManager();
fm.beginTransaction()
.replace(R.id.frag_container, new SettingsFragment())
.commit();
我将 replace()
调用更改为 add()
调用,现在它可以正常工作了。似乎 activity 在布局 中添加了两个相同的片段,当它在方向改变时被重新创建。使用 replace 解决了这个问题,因为它不会向 activity 添加多个片段。这个故事的寓意:如有疑问,请使用 replace()
,而不是 add()
。
我有一个 activity(扩展 AppCompatActivity),其中包含 PreferenceFragment
和我的应用设置。第一个设置是用于启用或禁用通知的 SwitchPreference,然后是依赖于该 SwitchPreference 的其他首选项。
我的问题是:我发现如果我旋转设备(导致方向改变)然后点击开关,它不会正确呈现 - 它似乎显示两个重叠的开关(here's a screencap from a Moto X), one in the old position and one in the new position. Interestingly, this even happens with the older style of switches (here's a screencap from a Nexus S running JellyBean ).
我在互联网上没有发现任何关于此错误的信息,据我所知,它不会发生在 Android OS 应用程序(例如“设置”)或其他第三方应用程序(例如 Intrications Intent Intercept)。所以看来我只是在这里做错了什么。
这是我的 SettingsFragment 中的设置代码:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings);
// Grab Preference objects
final Preference wklyRemPref = findPreference(getString(R.string.prefkey_weekly_reminder));
// Set up notification settings
findPreference(getString(R.string.prefkey_allow_notifs))
.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (Boolean.FALSE.equals(newValue)) {
// Turn off and disable "Weekly Reminder" pref
((TwoStatePreference) wklyRemPref).setChecked(false);
// (Disabling is done by the system because the "Weekly Reminder"
// preference depends on the "Notifications" preference)
}
return true;
}
});
wklyRemPref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
Log.d("Pref", preference + " value changed (" + newValue + ")");
return true;
}
});
...
}
这是我的 settings.xml
文件:
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="Reminders">
<SwitchPreference
android:defaultValue="true"
android:key="@string/prefkey_allow_notifs"
android:title="@string/allow_notifs"/>
<!-- Weekly reminder: -->
<CheckBoxPreference
android:dependency="@string/prefkey_allow_notifs"
android:defaultValue="true"
android:key="@string/prefkey_weekly_reminder"
android:summary="Remind me weekly to choose a scripture"
android:title="Weekly reminder" />
<net.danmercer.ponderizer.settings.ReminderPreference
android:defaultValue="sunday/17:00"
android:dependency="@string/prefkey_weekly_reminder"
android:key="@string/prefkey_weekly_reminder_time"
android:title="Set weekly reminder time" />
<!-- Notification preferences -->
<RingtonePreference
android:dependency="@string/prefkey_allow_notifs"
android:key="@string/prefkey_notif_sound"
android:title="Notification Sound"
android:ringtoneType="notification"
android:showDefault="true"
android:showSilent="true"/>
<CheckBoxPreference
android:defaultValue="true"
android:dependency="@string/prefkey_allow_notifs"
android:key="@string/prefkey_notif_vibrate"
android:title="Vibrate" />
</PreferenceCategory>
...
</PreferenceScreen>
编辑: 我还尝试清理并重建我的项目,卸载并重新安装该应用程序,但无济于事。
编辑 2: 我尝试使用 CheckBoxPreference 而不是 SwitchPreference 并遇到了同样的问题。更糟糕的是,当我旋转 activity 时,我发现整个片段似乎都被烧进了屏幕(可以这么说)。我可以滚动设置片段,但它之前的样子仍然存在。这个神器早些时候表现为两个重叠的开关,但我没有意识到它如此普遍。
我发现了问题。在我的 SettingsActivity onCreate() 方法中,我有这样的代码:
FragmentManager fm = getFragmentManager();
fm.beginTransaction()
.replace(R.id.frag_container, new SettingsFragment())
.commit();
我将 replace()
调用更改为 add()
调用,现在它可以正常工作了。似乎 activity 在布局 中添加了两个相同的片段,当它在方向改变时被重新创建。使用 replace 解决了这个问题,因为它不会向 activity 添加多个片段。这个故事的寓意:如有疑问,请使用 replace()
,而不是 add()
。