gho*_*ost 5 android android-preferences android-fragments
根据Android指南,我正在尝试使用Preference Fragments实现首选项.在preferences.xml我声明:
<SwitchPreference
android:key="enable_wifi"
android:title="Enable WiFi"
/>
Run Code Online (Sandbox Code Playgroud)
而且在课堂上thah在onCreate方法中扩展了PreferenceFragment,我做了:
public class FragmentSettings extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
mEnableWifi = (SwitchPreference) findPreference(enable_wifi);
mEnableWiFi.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
Log.i(getClass().getName(), preference.getKey()
+ String.valueOf(newValue));
}
}
Run Code Online (Sandbox Code Playgroud)
因此,当我登录SwitchPreferene或Switch内部日志显示时,我得到了
enable_wifi false
enable_wifi false
enable_wifi true
enable_wifi true
Run Code Online (Sandbox Code Playgroud)
所以这就是为什么我认为监听器被多次调用.如何处理或修复它?
Man*_*ani 11
这是由于SwitchPreference实施中的错误.
回调onPreferenceChange被称为:
SharedPreference.Switch窗口小部件的切换状态.在这里它被调用.无法评论逻辑,但至少onPreferenceChange只有在状态发生变化时,框架才应该注意调用回调.所以责任在于我们.使用SwitchPreference.isChecked方法检查状态是否已更改.
public boolean onPreferenceChange(Preference preference, Object newValue) {
if(((SwitchPreference) preference).isChecked() != (Boolean) newValue) {
// State got changed
Log.i("Testing", preference.getKey() + " : " + String.valueOf(newValue));
// If you don't want to save the preference change return false from this if block.
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
这是callstack供您参考:
TwoStatePreference.onClick:
MainActivity$SettingsFragment$1.onPreferenceChange(Preference, Object) line: 45
SwitchPreference(Preference).callChangeListener(Object) line: 895
SwitchPreference(TwoStatePreference).onClick() line: 65
SwitchPreference(Preference).performClick(PreferenceScreen) line: 950
PreferenceScreen.onItemClick(AdapterView, View, int, long) line: 215
ListView(AdapterView).performItemClick(View, int, long) line: 298
ListView(AbsListView).performItemClick(View, int, long) line: 1100
AbsListView$PerformClick.run() line: 2788
AbsListView$1.run() line: 3463
Handler.handleCallback(Message) line: 730
ViewRootImpl$ViewRootHandler(Handler).dispatchMessage(Message) line: 92
Looper.loop() line: 137
Run Code Online (Sandbox Code Playgroud)
切换小部件切换:
MainActivity$SettingsFragment$1.onPreferenceChange(Preference, Object) line: 45
SwitchPreference(Preference).callChangeListener(Object) line: 895
SwitchPreference$Listener.onCheckedChanged(CompoundButton, boolean) line: 47
Switch(CompoundButton).setChecked(boolean) line: 126
Switch.setChecked(boolean) line: 666
SwitchPreference.onBindView(View) line: 106
Run Code Online (Sandbox Code Playgroud)
奇怪的是,OP 的代码缺少 的 return 语句onPreferenceChange。
确保您return true;在最后调用,以便确实更改首选项。
但是,如果问题仍然存在,请在首选项更改侦听器内部进行检查,以便它不会进行不必要的更新:
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (preference.isEnabled() != newValue) {
// Do something on normal switch
return true;
} else {
// Preference wasn't changed, do nothing and don't update it
return false;
}
}
Run Code Online (Sandbox Code Playgroud)