Home » Android » android – PreferenceActivity update summary

android – PreferenceActivity update summary

Posted by: admin June 15, 2020 Leave a comment

Questions:

I have a PreferenceActivity with a 2 level tree of PreferenceScreens, something like:

<PreferenceScreen>
  <PreferenceScreen android:key="A">
     <ListPreference/>
     <EditTextPreference/>
  </PreferenceScreen>
  <PreferenceScreen android:key="B">
     <ListPreference/>
     <EditTextPreference/>
  </PreferenceScreen>
  ...
</PreferenceScreen>

Each of the lower level preference screens, e.g., A and B, is collecting two related pieces of data. I want the summary for those parent items to be a combination of the current values of the two sub preferences.

I tried adding onPreferenceChangeListener’s on the leaf preferences and updating the summary from there, but it doesn’t seem to take. The preferences are all created programmatically within the activity, so I’m doing something like this in onCreate:

   leafListPref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
       @Override
       public boolean onPreferenceChange(Preference preference, Object newValue) {
              // do some work
              prefScreenA.setSummary( /* get new summary based on newValue */);
              return true;
       }
  });

I then tried to find a location where I can be informed that I have returned to the top level preferences screen from a subpage so that I can update at that point. However, I am confused as to how the lower level screens are being displayed. It looks like they are actually dialogs, not full Activities since onPause/onResume is not called when moving between them. Is there some method somewhere that I’m missing that will be called when returning to the top level page?

I also tried adding a sharedPreferenceChangeListener, as described here, but that never seems be called.

Anyone have any hints on what I’m missing here, or any easier approach I’m missing?

How to&Answers:

I had the same problem and it seems that calling Activity.onContentChanged() after the summary is changed corrected my problem.

@Override
public void onSharedPreferenceChanged(SharedPreferences sp, String key) {
  // Update summary value
  EditTextPreference pref = (EditTextPreference)findPreference(key);
  pref.setSummary(pref.getText());
  this.onContentChanged();
}

Answer:

After a truly asinine amount of trial and error, I finally found the answer in another SO answer. Here’s the magic line:

((BaseAdapter)getPreferenceScreen().getRootAdapter()).notifyDataSetChanged();

Put that in your preference listener, then you’re good to go.

Answer:

Use the following code and override onContentChanged()

   public class SettingsActivity extends PreferenceActivity
    {
         @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.preferences);
            setContentView(R.layout.settings_layout);


            }

@Override
    public void onContentChanged() {
        // put your code here
        super.onContentChanged();
    }

}

Hope it helps.

Answer:

I also faced this problem and I finally found a solution by using the value coming from the listener.
In my example below (for a ListPreference), I first get the index of the value in the ListPreference array, then I retrieve the label of the value using this index:

passwordFrequencyLP.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
        @Override
        public boolean onPreferenceChange(Preference preference, Object newValue) {
            int newFrequency = Integer.valueOf(newValue.toString());

            prefs.edit().putInt("settings_key_password_frequency", newFrequency).commit();

            //get the index of the new value selected in the ListPreference array
            int index = passwordFrequencyLP.findIndexOfValue(String.valueOf(newValue));
            //get the label of the new value selected
            String label = (String) passwordFrequencyLP.getEntries()[index];

            passwordFrequencyLP.setSummary(label);

            makeToast(getResources().getString(R.string.password_frequency_saved));
            return true;
        }
    });

This little trick works well, I found many different possible solutions to this problem but only this one worked for me.