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();
} }
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With