Setting Preference Summary/Label for ListPreference

ListPreference items in Preference screens do not automatically provide a label showing their current value. You can create labels for all list Preference items as so:

In the Settings Fragment onCreatePreferences override, get the Shared Preferences and the Preference screen. Then iterate through all of the Preferences in the screen, checking whether they are tickboxes. Any that aren't will have their value stored and passed to a setPreferenceSummary function along with the Preference itself:

    @Override
    public void onCreatePreferences(Bundle bundle, String s) {

        addPreferencesFromResource(R.xml.pref_xxxxx); // Reference to xml resource
        SharedPreferences sharedPreferences = getPreferenceScreen().getSharedPreferences(); // Retrieve the Shared Preferences from the Preference screen
        PreferenceScreen preferenceScreen = getPreferenceScreen(); // Retrieve the Preference screen
        int count = preferenceScreen.getPreferenceCount(); // The number of Preferences within the screen

        for (int i = 0; i < count; i++ ) { // For each Preference...
            Preference p = preferenceScreen.getPreference(i); // ...retrieve the Preference...
            if (!(p instanceof CheckBoxPreference)) { // ...make sure it isn't a checkbox...
                String value = sharedPreferences.getString(p.getKey(), ""); // ...then retrieve its value (can't use getString on a Boolean, so another reason to exclude tickboxes)...
                setPreferenceSummary(p, value); // ...and send the Preference and its value to the setPreferenceSummary function
            }
        }
    }

The setPreferenceSummary function is as follows:

    private void setPreferenceSummary(Preference preference, String value) {
        if (preference instanceof ListPreference) { // If it is a ListPreference...
            ListPreference listPreference = (ListPreference) preference; // ...cast it to an object of type ListPreference...
            int prefIndex = listPreference.findIndexOfValue(value); // ...retrieve the index of that value...
            if (prefIndex >= 0) {
                listPreference.setSummary(listPreference.getEntries()[prefIndex]); // ...and get the corresponding label for it, setting it as the Preference Summary
            }
        } else if (preference instanceof EditTextPreference) {
            // For EditTextPreferences, set the summary to the value's simple string representation.
            preference.setSummary(value);
        }
    }

Implement an OnSharedPreferenceChangeListener to make sure changes are implemented without having to force an onCreate (e.g. device rotation). Within the required onSharedPreferenceChanged override, again check to see if the preference is not a checkbox, and if so send the preference to the setPreferenceSummary function along with its value:

public class SettingsFragment extends PreferenceFragmentCompat implements OnSharedPreferenceChangeListener {

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
        Preference preference = findPreference(key);
        if (preference != null) {
            if (!(preference instanceof CheckBoxPreference)) {
                String value = sharedPreferences.getString(preference.getKey(), "");
                setPreferenceSummary(preference, value);
            }
        }
    }
}

Register and unregister the OnSharedPreferenceChangeListener with the following overrides:

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
    }

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

Settings or Preferences – Making Changes In App

How to make user changes to options within the Settings Fragment affect changes in the app.

In the Activity call a function to setup shared preferences, then create that function. We will also link the shared preference object with the onSharedPreferenceChangeListener using .registerOnSharedPreferenceChangeListener:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_xxxxx);
        mTargetView =  findViewById(R.id.activity_xxxxx); // View to be affected by the preference change
        setupSharedPreferences(); // Call custom function to set up preferences
    }

    private void setupSharedPreferences() {
        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); // Get a reference to the default shared preferences from the PreferenceManager class
        mTargetView.setShowText(sharedPreferences.getBoolean(getString(R.string.pref_xxxxx), getResources().getBoolean(R.bool.pref_xxxxx_default))); // Get the value of a preference and use it to call a function (in this case, the custom function mTargetView.setShowText) which will change behaviour in the app
        sharedPreferences.registerOnSharedPreferenceChangeListener(this); // We can use 'this' as context as the Activity will implement OnSharedPreferenceChangeListener (see next)
    }

To make sure the Activity implements the change without having to force an onCreate (e.g.rotate device) implement an OnSharedPreferenceChangeListener within the relevant Activity:

public class xxxxxActivity extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener {

    @Override
    public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { // This function already passes us a reference to the sharedPreferences and key, so we don't need to use the PreferenceManager
        if (key.equals(getString(R.string.pref_show_bass_key))) {
            mTargetView.setShowBass(sharedPreferences.getBoolean(key, getResources().getBoolean(R.bool.pref_show_text_default)));
        }
    }
}

Unregister the OnSharedPreferenceChangeListener when the Activity is shut down using .unregisterOnSharedPreferenceChangeListener:

    @Override
    protected void onDestroy() {
        super.onDestroy();
        PreferenceManager.getDefaultSharedPreferences(this).unregisterOnSharedPreferenceChangeListener(this);
    }

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