PreferenceFragment OnPreferenceClickListener() works only once
android, onclicklistener, reset, sharedpreferences
Solution
When you call the `setPreferenceScreen(null);` all the data and listeners of the screens is removed. Then by calling `addPreferencesFromResource(R.xml.preferences);` you add the data but not the listeners.
So to make `Preference` reset to work you need to add the listener again!
I suggest you create a method
private void addMyResetListener() {
Preference reset = (Preference) findPreference("reset");
reset.setOnPreferenceClickListener(new OnPreferenceClickListener()
{
public boolean onPreferenceClick(Preference pref)
{
resetSettings(SettingsFragment.this.getActivity());
return true;
}
});
}
And use it after the
setPreferenceScreen(null);
addPreferencesFromResource(R.xml.preferences);
addMyResetListener();
So `resetSettings` changes to
public void resetSettings(Context ctx) // also removed static
{
PreferenceManager
.getDefaultSharedPreferences(ctx)
.edit()
.clear()
.commit();
PreferenceManager.setDefaultValues(ctx, R.xml.preferences, true);
setPreferenceScreen(null);
addPreferencesFromResource(R.xml.preferences);
addMyResetListener();
}
That way you do not need a custom preference `ResetPreference`
Problem
I'm implementing a custom `Preference` that shall behave similar to a button (the preference will open up a dialog for restoring the default values of all preferences). It's working fine if you click on the `ResetPreference` the dialog shows and on positive click all preference data is cleared and reset, but if you click on the `ResetPreference` again nothing happens. I suppose that while setting the `PreferenceScreen` to null and re-adding the resources something is amiss. If you ask why I used this approach, I wanted to click on reset and directly show the result of the change, if anyone knows a better way to implement a reset please give a little example. PS: If clicking on the `ResetPreference` and selecting the negative button nothing happens and the listener is still functional so it should really have something to to with deleting and re-adding the resources. ResetPreference.java ``` public class ResetPreference extends Preference { public ResetPreference(Context context, AttributeSet attrs) { super(context, attrs); setOnPreferenceClickListener(new OnPreferenceClickListener() { public boolean onPreferenceClick(Preference preference) { AlertDialog.Builder builder = new AlertDialog.Builder(getContext()); builder.setTitle(R.string.prefAlertDialog_Title); builder.setMessage(R.string.prefAlertDialog_Message); builder.setPositiveButton(R.string.prefAlertDialog_Positive, new OnClickListener() { public void onClick(DialogInterface dialog, int which) { SettingsFragment.resetSettings(getContext()); } }); builder.setNegativeButton(R.string.prefAlertDialog_Negative, null); builder.create().show(); return false; } }); }} ``` Then there is my custom PreferenceFragment SettingsFragment.java ``` public class SettingsFragment extends PreferenceFragment{ private static SettingsFragment sf = null; public static void resetSettings(Context ctx) { PreferenceManager .getDefaultSharedPreferences(ctx) .edit() .clear() .commit(); PreferenceManager.setDefaultValues(ctx, R.xml.preferences, true); if(sf != null) { sf.setPreferenceScreen(null); sf.addPreferencesFromResource(R.xml.preferences); } } public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); sf = this; // Load the preferences from an XML resource addPreferencesFromResource(R.xml.preferences); Preference reset = (Preference) findPreference("reset"); reset.setOnPreferenceClickListener(new OnPreferenceClickListener() { public boolean onPreferenceClick(Preference pref) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setTitle(R.string.prefAlertDialog_Title); builder.setMessage(R.string.prefAlertDialog_Message); builder.setPositiveButton(R.string.prefAlertDialog_Positive, new OnClickListener() { public void onClick(DialogInterface dialog, int which) { PreferenceManager .getDefaultSharedPreferences(getActivity().getApplicationContext()) .edit() .clear() .commit(); PreferenceManager.setDefaultValues(getActivity().getApplicationContext(), R.xml.preferences, true); setPreferenceScreen(null); addPreferencesFromResource(R.xml.preferences); } }); builder.setNegativeButton(R.string.prefAlertDialog_Negative, null); builder.create().show(); return true; } }); } @Override public void onStop() { super.onStop(); sf = null; }} ``` After adding the suggestion from https://stackoverflow.com/a/24648780/3387852 everything is done in the `SettingsFragment`. The `ResetPreference` is no longer needed and the standard android `Preference` can be used instead. The only code needed to implement the reset button is in this updated SettingsFragment.java ``` public class SettingsFragment extends PreferenceFragment{ private void addMyResetListener() { Preference reset = (Preference) findPreference("reset"); reset.setOnPreferenceClickListener(new OnPreferenceClickListener() { public boolean onPreferenceClick(Preference pref) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setTitle(R.string.prefAlertDialog_Title); builder.setMessage(R.string.prefAlertDialog_Message); builder.setPositiveButton(R.string.prefAlertDialog_Positive, new OnClickListener() { public void onClick(DialogInterface dialog, int which) { resetSettings(SettingsFragment.this.getActivity()); } }); builder.setNegativeButton(R.string.prefAlertDialog_Negative, null); builder.create().show(); return true; } }); } public void resetSettings(Context ctx) { //Remove all Settings PreferenceManager .getDefaultSharedPreferences(ctx) .edit() .clear() .commit(); //All Settings that are empty will be loaded from default values again PreferenceManager.setDefaultValues(ctx, R.xml.preferences, true); setPreferenceScreen(null); addPreferencesFromResource(R.xml.preferences); addMyResetListener(); } public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Load the preferences from an XML resource & add listener addPreferencesFromResource(R.xml.preferences); addMyResetListener(); } } ```