Reputation: 46844
I have a PreferenceActivity
with a 2 level tree of PreferenceScreen
s, 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?
Upvotes: 8
Views: 7691
Reputation: 3180
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.
Upvotes: 1
Reputation: 17976
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.
Upvotes: 0
Reputation: 93
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.
Upvotes: 0
Reputation: 1615
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();
}
Upvotes: 12