Search code examples
androidsharedpreferencespreferenceactivity

Modifying a Preference value in PreferenceActivity has no effect before Activity is closed


I am just trying to change the value of a Preference when the PreferenceActivity has been opened. As there is no "setValue" or similar on a Preference, I try

My code:

long value = System.currentTimeMillis()/1000;
PreferenceManager.getDefaultSharedPreferences(getActivity()).edit().putString("test",""+value).apply();
getPreferenceScreen().findPreference("test").setSummary(""+value);

My XML:

<EditTextPreference
    android:key="test" />

What I expect:

When clicking on my Preference, it should display the value of time (same than summary) and let me edit it.

What happen:

The value is only changed after I closed the Activity. Next time I open the screen, the value is correct (but as in fact already changed to the next one)

First attempt: Let s say value is 1521143527. Correctly written in the summary, but when I click on the Preference, the popup display an empty value.

Second attemp: Summary has changed to 1521143540. When I click on Preference, I can edit the previous value (1521143527)

Third attempt: New Summary, but Preference value is not changed and is still: 1521143540

etc...

Any idea what is wrong?

DIRTY WORKAROUND:

    setPreferenceScreen(null);
    addPreferencesFromResource(R.xml.preferences);

Will now force the preference to update, but that's really dirty, and I still don't understand...


Solution

  • If you look into the PreferenceFragment source code ,you can see that there is a method called bindPreferences() which binds the preference values to Views . Only in 2 scenarios this method is called,

    1. When Activity created onActivityCreated(@Nullable Bundle savedInstanceState)

      1. When addPreferencesFromResource() called. there is a handler which triggers the bindPreferences()

    Other than this there is no way the views are updated. bindPreferences() is a private method , so you can't call this method outside of the class. So you should update your preferences before either those events.

    You mentioned, As a workaround solution, you should update your preference first then call addPreferencesFromResource() . Like below

         @Override
            public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                long value = System.currentTimeMillis()/1000;
                getPreferenceManager().getSharedPreferences().edit().putString("test",""+value).commit();
                addPreferencesFromResource(R.xml.pref_general);           
                getPreferenceScreen().findPreference("test").setSummary(""+value);
            }