Pregunta

Estoy tratando de construir mi preferencia utilizando fragmentos. Tengo una preferencia de fragmento que contiene dos pertenencias de cheques:

<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" />

Mi fragmentos de la actividad:

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));
        }
    }
}

La primera llamada de OnPreferenceChange establece el resumen correctamente, pero cualquier otra llamada establece el resumen contrario: si se verifica la casilla, se establece el resumen "sin control" y viceversa.

Parece que isChecked () devuelve algún tipo de valor incorrecto ya que value.toString () devuelve el estado correcto como una cadena.

Log () Impresiones:

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

¿Dónde está mi error?

¿Fue útil?

Solución

Desde el OnpreferenceChangelistener documentos:

Devoluciones
Es cierto para actualizar el estado de la preferencia con el nuevo valor.

Lo que se puede recopilar de esto es que el valor de la preferencia no cambia en realidad hasta que el oyente regrese verdadero. En otras palabras, el newValue parámetro de onPreferenceChange() es lo que será el valor, pero no lo que aún es actualmente (porque su verificación de registro está dentro del oyente, antes de que se haya devuelto True).

En una nota al margen, creo que el propósito de esto es para que pueda rechazar un cambio no válido a una preferencia. Por ejemplo, si la preferencia era una cadena, y se desea que solo acepte cadenas de una cierta matriz de valores aceptados, el Dev puede rechazar el cambio al devolver falso en onPreferenceChange().

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top