PreferenceChangeListener

The differences between PreferenceChangeListener and SharedPreferenceChangeListener are:

  • SharedPreferenceChangeListener is triggered after any value is saved to the SharedPreferences file.
  • PreferenceChangeListener is triggered before a value is saved to the SharedPreferences file. Because of this, it can prevent an invalid update to a preference.
  • PreferenceChangeListeners are also attached to a single preference.

So it can be used as follows:

  • User updates a preference.
  • PreferenceChangeListener triggered for that preference e.g. to validate input.
  • The new value is saved to the SharedPreference file.
  • onSharedPreferenceChanged listeners are triggered.

Implement Preference.OnPreferenceChangeListener:

public class SettingsFragment extends PreferenceFragmentCompat implements OnSharedPreferenceChangeListener, Preference.OnPreferenceChangeListener

In the override for onCreatePreferences attach the listener to the chosen Preference:

@Override
public void onCreatePreferences(Bundle bundle, String s) {
         /* Other preference setup code code */
        //...
        Preference preference = findPreference(getString(R.string.pref_xxxx_key)); // Key for the Preference to watch. Customise
        preference.setOnPreferenceChangeListener(this); // Attach the listener to the Preference
}

In this example we will use the onPreferenceChange override to validate the input and restrict it to a number between 0.1 and 3:

@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
   Toast error = Toast.makeText(getContext(), "Please select a number between 0.1 and 3", Toast.LENGTH_SHORT); // Error Toast if input invalid

   String xxxxKey = getString(R.string.pref_xxxx_key);
   if (preference.getKey().equals(xxxxKey)) {
       String stringInput = (String) newValue; // Cast the Object o a String
       try {
           float input = Float.parseFloat(stringInput); // Try converting to a float
           if (input > 3 || input <= 0) { // If outside the accepted range...
               error.show(); // ...show the error Toast...
               return false; // ...and fail to register the new change
           }
       } catch (NumberFormatException nfe) { // If cannot convert to float then throw an exception
           error.show();
           return false;
       }
   }
   return true; // Otherwise accept the value
}

ud851-Exercises-student\Lesson06-Visualizer-Preferences\T06.10