2013-10-21 11 views
5

the Android guide के अनुसार कई बार कॉल करता है मैं वरीयता टुकड़ों का उपयोग करके वरीयताओं को लागू करने की कोशिश कर रहा हूं। preferences.xml में मैं घोषणा:स्विचप्रिएंशन ऑनपेरेंशन चेंज() विधि

<SwitchPreference 
     android:key="enable_wifi" 
     android:title="Enable WiFi" 
     /> 

और वर्ग 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)); 
    } 
} 

और एक परिणाम के रूप मुझे मिल गया जब मैं SwitchPreferene पर clik या लॉग शो अंदर स्विच

enable_wifi false 
enable_wifi false 
enable_wifi true 
enable_wifi true 

इसलिए मुझे लगता है कि श्रोता को कई बार बुलाया जाता है। इसके साथ कैसे संभालें या इसे ठीक करें?

उत्तर

1

यह अजीब बात है कि ओपी के कोड में 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; 
    } 
} 
+0

यदि समस्या अनुपलब्ध 'वापसी' कथन थी, तो कोड भी संकलित होगा? लॉग इंगित करता है कि कोड बस ठीक है। – Vikram

+0

@ विक्रम अगर वापसी का विवरण गुम है, तो शायद कुछ और भी है? हम कैसे बता सकते हैं कि समस्या कहां है? हम जो भी कर सकते हैं वह अनुमान है :-) – Simas

+0

मैं बिल्कुल आपके साथ सहमत हूं - यह कहने में कठिनाई है कि समस्या कहां है। मैं केवल इतना कहना चाहता था कि कोड एक लापता वापसी कथन के साथ संकलित नहीं होगा। हालांकि यह एक अच्छा पकड़ था :)) – Vikram

11

यह SwitchPreference कार्यान्वयन में बग के कारण है।

कॉलबैक onPreferenceChange कहा जाता है: TwoStatePreference.onClick विधि, जो सिर्फ SharedPreference अद्यतन करता है के द्वारा

  • पहली बार।
  • Switch विजेट की टॉगल स्थिति द्वारा दूसरी बार। Here इसे बुलाया गया है।

तर्क पर टिप्पणी नहीं कर सकता है, लेकिन कम से कम ढांचे को राज्य में बदलाव होने पर ही 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; 
} 

यहाँ आपके संदर्भ के लिए 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 

स्विच विजेट टॉगल:

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 
0

हो सकता है टुकड़ा की वस्तु में आयोजित की जा रही है स्मृति नष्ट होने पर भी स्मृति। तो जब फ्रैगमेंट फिर से बनाया जाता है तो पिछले खंड से श्रोता अभी भी वहां होता है और जो कॉलबैक आप देखते हैं वह दो अलग-अलग श्रोताओं से हो सकता है। कॉल की पुष्टि करने के लिए वास्तव में दो अलग श्रोताओं से है, कृपया ऑब्जेक्ट की टूस्ट्रिंग विधि को मुद्रित करने का प्रयास करें।

@Override 
public boolean onPreferenceChange(Preference preference, Object newValue) { 
    Log.i(getClass().getName(), preference.getKey() + String.valueOf(newValue)); 
    Log.i(getClass().getName(), this.toString()); 
} 

आप toString तो मैं टुकड़ा के onDestory में श्रोता को हटाने लगता है कि आप के लिए समस्या का समाधान हो सकता है के लिए अलग मान मिलता है।

@Override 
public void onDestroy() { 
    super.onDestroy(); 
    mEnableWifi.setOnPreferenceChangeListener(null); 
} 
संबंधित मुद्दे