2013-11-07 5 views
3

Я пытаюсь создать свою функцию PreferenceActivity с помощью фрагментов. У меня есть PreferenceFragment, содержащий два CheckBoxPreferences:CheckBoxPreference .isChecked() возвращает значение противоположности

<CheckBoxPreference 
    android:key="pref_bfp_scale" 
    android:title="@string/PREF_BFP_scale_title" 
    android:defaultValue="false" /> 
<CheckBoxPreference 
    android:key="pref_bfp_navy" 
    android:title="@string/PREF_BFP_navy_title" 
    android:defaultValue="true" /> 

Мой FragmentSettingsActivity:

public class FragmentSettingsActivity extends PreferenceActivity { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
    } 

    public static class BodyFatPreferenceFragment extends PreferenceFragment { 
     @Override 
     public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      addPreferencesFromResource(R.xml.pref_body_fat); 
      bindPrefSumtoValListener(findPreference("pref_bfp_scale"), "Boolean"); 
      bindPrefSumtoValListener(findPreference("pref_bfp_navy"), "Boolean"); 
     } 
    } 

    private static Preference.OnPreferenceChangeListener prefSumtoValListener = new Preference.OnPreferenceChangeListener() { 
     @Override 
     public boolean onPreferenceChange(Preference preference, Object value) { 
      String stringValue = value.toString(); 
      log("Pref changed - Value: " + stringValue); 

      if (preference instanceof CheckBoxPreference) { 
       Map<String, Integer> checkboxes = new HashMap<String, Integer>(); 

       checkboxes.put("pref_bfp_navy_unchecked", R.string.PREF_BFP_navy_summary_unchecked); 
       checkboxes.put("pref_bfp_navy_checked", R.string.PREF_BFP_navy_summary_checked); 
       checkboxes.put("pref_bfp_scale_unchecked", R.string.PREF_BFP_scale_summary_unchecked); 
       checkboxes.put("pref_bfp_scale_checked", R.string.PREF_BFP_scale_summary_checked); 

       log(Boolean.toString(((CheckBoxPreference) preference).isChecked())); 
       log(String.format("? : %s_%s", preference.getKey(), ((CheckBoxPreference) preference).isChecked()? "checked" : "unchecked")); 

       preference.setSummary(checkboxes.get(String.format("%s_%s", preference.getKey(), ((CheckBoxPreference) preference).isChecked()? "checked" : "unchecked"))); 
      } 

      return true; 

     } 
    }; 

    private static void bindPrefSumtoValListener(Preference preference, String type) { 
     SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(preference.getContext()); 

     preference.setOnPreferenceChangeListener(prefSumtoValListener); 

     if (type.equals("Boolean")) { 
      prefSumtoValListener.onPreferenceChange(preference, sharedPreferences.getBoolean(preference.getKey(), false)); 
     } 
    } 
} 

Первый вызов onPreferenceChange устанавливает резюме правильно, но каждый вызов устанавливает противоположное резюме: Если флажок установлен, «unchecked» summary задано и наоборот.

Кажется, что isChecked() возвращает какое-то неправильное значение, так как value.toString() возвращает правильное состояние как String.

журнала() печатает:

log("Pref changed - Value: " + stringValue); 
    //Output: Pref changed - Value: true 
log(Boolean.toString(((CheckBoxPreference) preference).isChecked())); 
    //Output: false 
log(String.format("? : %s_%s", preference.getKey(), ((CheckBoxPreference) preference).isChecked()? "checked" : "unchecked")); 
    //Output: ? : pref_bfp_navy_unchecked 

Где моя ошибка?

ответ

6

Из OnPreferenceChangeListener документов:

Возвращает
Правда, чтобы обновить состояние Preference с новым значением.

Что можно почерпнуть из этого является то, что значение предпочтения фактически не изменится, пока слушатель не возвращает истинную. Другими словами, параметр newValueonPreferenceChange() является тем значением, которое будет стоить, но не тем, чем он является на данный момент (поскольку проверка журнала находится внутри слушателя, до того, как возвращается истина).

На стороне примечания, я думаю, цель этого заключается в том, что вы можете отклонить недействительное изменение к предпочтению. Например, если предпочтение было строкой, и желательно, чтобы он принимал только строки из определенного массива принятых значений, разработчик может отклонить изменение, вернув false в onPreferenceChange().

+1

Другими словами: я должен использовать, например, 'boolean checked = (Boolean) newValue;' для получения текущего значения CheckBox, потому что новое значение будет сохранено после 'onPreferenceChange()'. Спасибо! – Kurztipp

Смежные вопросы