1
votes

This may be complicated to understand, so feel free to ask any clarification

  1. I have one class which extends PreferenceFragment and load a default preferences file: this.addPreferencesFromResource(R.xml.settings);

  2. I've one Activity which displays this fragment and listen to changes on the application preferences in order to avoid invalid values being setted by user

@Override
        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { 
    /*do my stuff */  
        }

Everything is running fine, the user gets a dialog when tries to change to an invalid value and they are not saved to preferences but I have a problem:

My settings.xml is something like this:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">

    <EditTextPreference

        android:defaultValue="5"
        android:inputType="number"
        android:key="@string/pref_comment"
        android:persistent="true"
        android:title="@string/comment" /> 

and the resulting screen looks like: enter image description here

1-When the user taps any option a dialog (controled by android preference api) pops up, if he changes the value it triggers the onSharedPreferenceChanged and runs my logic

2-When I reject the value passed by user and block the change, I display a pop up to user saying that the change was invalid, I dont persist that value but the preference activity still keeps the invalid value in the inner dialog... So if he tries to open the same option again will show the invalid value. What leads the user to think the value was saved...

the question is:

Is there any way to change the content of an inner dialog in android PreferenceFragment?

1

1 Answers

2
votes

You should implement Preference.OnPreferenceChangeListener for PreferenceFragment class. Then override onPreferenceChange method and if newValue is correct return true otherwise return false. If you return false then preference value will not change.

public class SettingsFragment extends PreferenceFragmentCompat implements
    Preference.OnPreferenceChangeListener {

       @Override
       public boolean onPreferenceChange(Preference preference, Object newValue) {

             int number = 0;
             try{
                   number = Integer.parseInt(newValue.toString());
              }catch(Exception e){

              }

              if (number > 0 && number < 10){    //It's an example
                     return true;                // Preference will change
              }

              return false;          // newValue rejected and preference not change
       }

}

After that you must set this listener to the corresponding preference. Do it inside onCreatePreference.

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

    addPreferencesFromResource(R.xml.settings);

    PreferenceScreen prefScreen = getPreferenceScreen();
    Preference editTextPrefernce = prefScreen.findPreference(getString(R.string.pref_key));

    if (editTextPrefernce != null && editTextPrefernce instanceof EditTextPreference) {
        editTextPrefernce.setOnPreferenceChangeListener(this);
    }
}

Enjoy it.