I have a CheckBoxPreference in a FragmentPreference. When the user active the check box, I check if an application is installed and if not, I reset the preference on false and I open the Play Store to download the app.
Basically all works fine, but I have an issue to refresh the UI. Indeed, even if I set the preference on false before opened the Play Store, when the user come back, the box is checked (the fragment has just been paused and resumed so the preference value is ignored).
Is there a way to "refresh" the activity or the fragment?
Make your PreferenceFragment implement the OnSharedPreferenceChangeListener interface.
In onCreate(), you can read the preference value and set the UI accordingly. For instance:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource.
addPreferencesFromResource(R.xml.shakesql_app_prefs);
// Initialize pref summary label.
// Get a reference to the application default shared preferences.
SharedPreferences sp = getPreferenceScreen().getSharedPreferences();
// Read the current preference value.
String listVal =
sp.getString(getString(R.string.preference_font_size_key),
getString(R.string.preference_font_size_default));
// Look up the textual description corresponding to the
// preference value and write it into the summary field.
String listDesc = descriptionFromPref(
listVal,
getResources().getStringArray(
R.array.preference_font_size_values),
getResources().getStringArray(
R.array.preference_font_size_labels)
);
if (!TextUtils.isEmpty(listDesc)) {
ListPreference listPref =
(ListPreference) findPreference(getString(R.string.preference_font_size_key));
listPref.setSummary(listDesc);
}
}
Then, in onSharedPreferenceChanged(), update the UI.
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Preference pref = findPreference(key);
if (pref instanceof ListPreference) {
// Update display title
// Write the description for the newly selected preference
// in the summary field.
ListPreference listPref = (ListPreference) pref;
CharSequence listDesc = listPref.getEntry();
if (!TextUtils.isEmpty(listDesc)) {
pref.setSummary(listDesc);
}
}
}
Here's a code snippet from the AdvancedPreferences sample in API Demos to force the value of a checkbox preference.
// Toggle the value of mCheckBoxPreference.
if (mCheckBoxPreference != null) {
mCheckBoxPreference.setChecked(!mCheckBoxPreference.isChecked());
}
Related
I'm a bit unclear on how Preference.setSummary() is supposed to work. Is this method supposed to update a menu item's summary in a Preference fragment in a non-volatile way? In other words, is the displayed summary supposed to persist after closing and re-opening the preference menu fragment?
I thought it is supposed to work like this, yet any time I press the back button and then re-open the preference menu the summaries are blank again.
public class FragmentSettingsMenu extends com.takisoft.fix.support.v7.preference.PreferenceFragmentCompat {
private SharedPreferences.OnSharedPreferenceChangeListener listener;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from the XML resource
addPreferencesFromResource(R.xml.preferences);
listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
if (key.equals("pref_wood")) {
Preference woodPref = findPreference(key);
String color = woodPref.getSharedPreferences().getString(key, "Maple");
MainActivity.getGLSurfaceView().setTexture(color);
woodPref.setSummary(color); // Set summary to be the user-description for the selected value
}
}
};
}
}
Is this method supposed to update a menu item's summary in a Preference fragment in a non-volatile way?
No.
In other words, is the displayed summary supposed to persist after closing and re-opening the preference menu fragment?
No.
Okay so I'm trying to make sense of how Shared Preference works with Preference.
Below is part of an app that works, but I do not understand how it works for the part of Shared Preference.
I have a UserPrefActivity.java containing the following code
public class UserPrefActivity extends PreferenceActivity {
//a preference value change listener that updates the preference summary
//to reflect its new value
private static Preference.OnPreferenceChangeListener
sBindPreferenceSummaryToValueListerner = new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
//gets string value of object
String value = newValue.toString();
Log.e("in sBind Listener", value);
//if the preference is a list preference, get the value at a given index
if (preference instanceof ListPreference) {
//for list preference look up the correct display value
//in the preference entries array
ListPreference listPreference = (ListPreference) preference;
int index = listPreference.findIndexOfValue(value);
//set the summary to reflect the new value
preference.setSummary(index >= 0 ? listPreference.getEntries()[index] : null);
} else {
//set summary to only value
preference.setSummary(value);
}
return true;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//call the deprecated method to load the preference screen
addPreferencesFromResource(R.xml.user_pref);
//get default Shared preference from preference screen
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
Preference saveNumPizza = findPreference("saveNumPizza");
//set the preference change listener to saveNumPizza
saveNumPizza.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListerner);
sBindPreferenceSummaryToValueListerner.onPreferenceChange(saveNumPizza,
PreferenceManager
.getDefaultSharedPreferences(this)
.getString(saveNumPizza.getKey(), ""));
}
}
In the MainActivity.java, I have the following as part of a bigger piece of code
//gets the default shared preference instance and assign to sharedPrefs for enabled save
// data
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences
(MainActivity.this);
//checks if save order status is true
if (sharedPrefs.getBoolean("saveOrder", false)) {
//do stuff..
}
I have the following UserPref.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference
android:defaultValue="false"
android:key="saveOrder"
android:summary="for quick loading of favourite order"
android:title="Enable Saving Order"/>
<PreferenceCategory android:title="ORDER HISTORY">
<CheckBoxPreference
android:defaultValue="false"
android:key="keepHistory"
android:summary="of pizza orders"
android:title="Keep History"/>
<ListPreference
android:defaultValue="3"
android:dialogTitle="Choose how many to save"
android:entries="#array/number_of_pizza"
android:entryValues="#array/number_of_pizza_values"
android:summary="3 pizza orders"
android:key="saveNumPizza"
android:title="Number of Orders"/>
</PreferenceCategory>
</PreferenceScreen>
I know that in the UserPrefsActivity, I believe in the PreferenceManager.getDefaultSharedPreferences(this) call, the shared preferences is created and obtained if it does not exist, if it does its just obtained.
From what I've noticed with the app, is that on first launch when I get to the settings and launch the UserPrefActivity via intent, the shared preference of the UserPrefActivity is created, containing only the saveNumPizza key. However the minute I click on the other preferences (Checkbox preference) when I look at the shared preference file, I immediately see that the saveOrder key and keepHistory key are automatically saved.
I would just like to know how this automatic saving is exactly done since I am not using an editor to save it to the shared preference, nor am I calling apply or commit.
Thank you,
I'm currently using a preference activity with fragments. I'm using android:summary in the xml file defining these preferences to set an explaining caption to the user and then setSummary on each preference when the user changes the preference value and everything works fine.
But when the user clears his/her choice in any EditTextPreference I would like to display back the explaining text from the xml tag android:summary. How could I achieve that?
Thanks in advance for your help.
OK I figured it out.
Just add a resource string for every preference key called "key_summary" and use it as android:summary in the xml file defining the preferences.
Then in the onSharedPreferenceChanged function, just load the corresponding string as the summary as follows:
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
{
Preference preference = findPreference(key);
if(preference instanceof EditTextPreference)
{
EditTextPreference editPref = (EditTextPreference)preference;
String szPref = editPref.getText();
if(null!=szPref&&0<szPref.length())
editPref.setSummary(szPref);
else
{
Activity activity = getActivity();
int nSummary = getResources().getIdentifier(key + "_summary", "string", activity.getPackageName());
if(0<nSummary)
editPref.setSummary(getString(nSummary));
else
editPref.setSummary(szPref);
}
}
}
I have a PreferenceActivity P that stores values to SharedPreferences. This is working--I am able to make selections from the lists and the summary values are displayed correctly.
The problem is when I attempt to access the SharedPreference values within Activity A. The default values are loaded instead of the stored values. Only after I access the PreferenceActivity from Activity A do the up-to-date SharedPreference values become available to Activity A. Any suggestions on how to resolve this? Is there any option to using PreferenceManager.getDefaultSharedPreferences?
Here is the bulk of the PreferenceActivity code (I omitted the onSharedPreferenceChanged listener for brevity):
public class P extends PreferenceActivity {
public static String KEY_PREF_show_watch_areas, KEY_PREF_time_format, KEY_PREF_date_format;
String PREF_show_watch_areas, PREF_time_format, PREF_date_format;
static SharedPreferences sharedPrefs;
Preference pref_show_watch_areas=null;
ListPreference pref_time_format=null, pref_date_format=null;
#SuppressWarnings("deprecation")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sharedPrefs = PreferenceManager.getDefaultSharedPreferences( getApplicationContext() );
KEY_PREF_show_watch_areas = getString(R.string.key_pref_show_watch_areas);
KEY_PREF_time_format = getString(R.string.key_pref_time_format);
KEY_PREF_date_format = getString(R.string.key_pref_date_format);
PREF_show_watch_areas = getString(R.string.pref_show_watch_areas);
PREF_time_format = getString(R.string.pref_time_format);
PREF_date_format = getString(R.string.pref_date_format);
//Load up the preference items (from XML)
addPreferencesFromResource(R.xml.preferences);
//DATE pref
pref_date_format = (ListPreference) findPreference(KEY_PREF_date_format); //Set summary to user selected value
pref_date_format.setSummary(pref_date_format.getEntry() );
//TIME pref
pref_time_format = (ListPreference) findPreference(KEY_PREF_time_format); //Set summary to show user selected value
pref_time_format.setSummary(pref_time_format.getEntry());
}
} // [END P]
Here is the onResume in Activity A:
#Override
protected void onResume() {
super.onResume();
SharedPreferences sharedPrefsResume = PreferenceManager.getDefaultSharedPreferences(getApplicationContext() );
dateFormatPref = sharedPrefsResume.getString(P.KEY_PREF_date_format, "d-MMM-yy");
timeFormatPref = sharedPrefsResume.getString(P.KEY_PREF_time_format, "h");
} // [END onResume]
I've discovered and resolved the problem. I was trying to access the SharedPrefs values with uninitialized variables (e.g., P.KEY_PREF_date_format). That's the reason the default values were being returned. I've now moved the static variables to my MainActivity to ensure they are initialized. Voila. SharePreferences are working as expected now.
I use a Preference in a PreferenceActivity to load default values: when this specific Preference is clicked, something like this happens:
private String mResetKeys = "key1,key2,key3";
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
SharedPreferences.Editor prefs_editor = prefs.edit();
for (String current_pref : mResetKeys.split(",")) {
prefs_editor.remove(current_pref);
}
prefs_editor.commit();
But afterwards, the Preferences whose corresponding SharedPreference was reset still show the old value - it seems to be cached in the Preference. Only when I leave the PreferenceActivity and reopen it, the Preferences show the new values.
How can I update the PreferenceActivity programmatically?
I had a similar problem. This probably isn't the most correct fix but it worked for my purposes. Right after I did the commits, I called the Activity.recreate(); method.
The activity will restart (onDestroy()/onCreate()/etc) but for my purposes all I needed was a special handling on one preference. I listened for a certain preference with an OnPreferenceClickListener and made an alert dialog box with a kind of warning message and an option to change their mind. If they did want to change their mind, I did my commit of the new value to the preference activity and then called recreate() so that the checkbox preference would be updated.
However, I am also interested in a way to do this without recreating the activity...
Update preference value without reloading PreferenceActivity
from http://liquidlabs.ca/2011/08/25/update-preference-value-without-reloading-preferenceactivity/
Here is how to update default shared preference value of target element (in this case EditTextPreference)
public class YourCustomPreference extends PreferenceActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
}
// some logic goes above, when you want to reset value and update EditTextPreference value
// For convenience, I am going to wrap two different task in different methods
private void resetPreferenceValue() {
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this.getApplicationContext());
SharedPreferences.Editor prefEditor = sharedPref.edit(); // Get preference in editor mode
prefEditor.putString("your_edit_text_pref_key", "DEFAULT-VALUE"); // set your default value here (could be empty as well)
prefEditor.commit(); // finally save changes
// Now we have updated shared preference value, but in activity it still hold the old value
this.resetElementValue();
}
private void resetElementValue() {
// First get reference to edit-text view elements
EditTextPreference myPrefText = (EditTextPreference) super.findPreference("your_edit_text_pref_key");
// Now, manually update it's value to default/empty
myPrefText.setText("DEFAULT-VALUE"); // Now, if you click on the item, you'll see the value you've just set here
}
}