I wanted to create ListPreference which, when changed will also reload values of others ListPreference objects. I tried to do that by calling:
if(key.equals("important_pref")) {
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("some_pref", "some_val");
editor.apply();
}
in onSharedPreferenceChanged function.
It does the work but I need to reload preferences screen to see the efect. Is there a way to avoid that and reload values instantly?
My guess is that I can't do this that way, because the first commit needs to be ended before changing something else.
This is a very common requirement that is unfulfilled I'm afraid. You either have to reload the screen by hacks like setPreferencesScreen(null); or (better) register a SharedPreferencesChanged listener and update the prefs manually. See : update preferences values after changing them programatically
In your case you should add if clauses in your existing SharedPreferencesChanged listener to "hear" the change in the "some_pref" preference and update the displayed value manually.
Related
How do i update a Prefence UI instance that i created in a Setting Activity from another activity (Main Activity)?
I tried using these lines in Main Activity to update the Preference within Settings Activity, but I get ClassCastException.
Preference IsFeature =(Preference)((PreferenceActivity)context).findPreference((getString(R.string.key_enable_feature)));
IsFeature.setEnabled(True);
Just wondering whether theres another way to do this?
Any help, feedback or answers would be great!
You can try this:
In xml of settings get the "key" attribute from element you want to change (in bottom example it's "example_switch"). Than put this code in onClick method of button or wherever else you want to. This below takes the preference of switch in general settings and sets its value to false.
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putBoolean("example_switch", false); // "example_switch" - "key" attribute of your element | false - value
editor.commit();
I have this settings section where I allow users to change the languages displayed within the app. When the user chooses a different language, the activity is reloaded so that the change of language can be applied. But the problem is, when the user clicks back right after changing the language, the language shown in the background activity is still the same.
So my question is, what should I do to apply the change of language when I get back to some activity on the background? I suppose I should do something to detect the change in onResume method, but I'm not sure what it is. If you have any suggestions, please let me know.
Thank you.
After several attempts, I have found the solution to my problem. On my onCreate method, I get the SharedPreferences that contains the value of current language, and get the current language:
SharedPrefrences languagepref = getSharedPreferences("language",MODE_PRIVATE);
String language = languagepref.getString("languageToLoad", Locale.getDefault().getDisplayLanguage());
Then, in my onResume method, I assign the value of the above mentioned variable language to a local variable, and update the value of language. Then I compare these two variables - if they are different, I will destroy the current activity and start another:
#Override
public void onResume(){
super.onResume();
String oldLanguage = language;
language = languagepref.getString("languageToLoad", Locale.getDefault().getDisplayLanguage());
if (!oldLanguage.equals(language)){
finish();
startActivity(getIntent());
}
}
And voila, that did the trick!
I would suggest using SharedPreferences. You can store a lang key with the associated value in there and update it when necessary. In your onResume() methods you can get the lang value and then populate views according the value stored.
SharedPreferences sharedPreferences;
sharedPreferences = this.getSharedPreferences("MyActivity", Activity.MODE_PRIVATE);
String lang = sharedPreferences.getString("lang", "en-GB");
SharedPreferences.Editor editor;
editor = sharedPreferences.edit();
editor.putString("lang", "en-US").commit();
That's the basics you need to get going.
Have you tried restarting the Activity after the change is done ?
You can Simply use
finish();
startActivity(getIntent());
to refresh an activity whenever it detects a preference change.
The built in back pressed function does not refresh the code,so do this after u you change the language.
#Override
public void onBackPressed()
{
//new MainActivity();
Intent intent=new Intent(this,MainActivity.class);
startActivity(intent);
}
and in Main Activity class do this
public MainActivity() {
//1- This code is responsible for updating the change of all Strings from a language to another
//it will be called every time this activity is instantiated (da,since it is a constructor) , or when this activity gets
// called by an intent.
//2- Every String inside this Activity(ever fragment inside it ) will also be under the effect of change of language
LocalUtils.updateConfig(this);
}
Please review the following answer and add this to it. To get a full answer written by Roberto.B and LarsH:
Changing Locale within the app itself
I have a CheckBoxPreference defined as follows:
<CheckBoxPreference
android:defaultValue="true"
android:key="prefVisible"
android:summary="#string/pref_visible_summary"
android:title="#string/pref_visible" >
</CheckBoxPreference>
My application uses this preference to control the visibility of a view. When I first start my application (on a new wiped emulator) the view is not shown. However, when the I go to the preferences screen (activity) the checkbox is shown as checked.
Does this mean that the defaultValue attribute is not actually setting the preference but rather it's just setting the value of the checkbox if there is no underlying data (as would be the case on a brand new install). And does this also mean that the preference is set only after the user enters/exits the preferences screen (activity) for the first time, otherwise it's undefined?
Note that in order to get my app to work the way I intended it to work I relied on the default value argument to the preferences getter method as follows:
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
boolean isVisible = sharedPrefs.getBoolean("prefVisible", true); // default = true
This leaves me a bit confused as to why there are 2 ways to control the default value of a preference: defining it in the Xml or providing the default value in the getBoolean method.
No the preferences can be set if you call PreferenceManager.setDefaultValues. So if you call this when the first time the app is launched then your view will be shown.
You can read more at http://developer.android.com/guide/topics/ui/settings.html
I've implemented my own PreferenceFragment subclass (detailed here), and want to listen for preference changes within it. PreferenceFragment provides you with two ways of doing this:
getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
and
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
Which one should be used? What's the difference? I don't really understand the distinction made in the Android docs.
The core difference is in their names, PreferenceManger grants access to different functionalities to the developer for managing SharedPreferences, such as retrieving the map of current preference values or setting user preferences. to their default values. PreferenceScreen handles displaying a screen of user preferences, so that the user can assign values to them. Sometimes this means displaying a list item on a screen with other preferences, that opens another screen with more preferences when clicked, as is the case when PreferenceScreens are nested.
Your question implies that you think there is a difference between what PreferenceManager.getSharedPreferences() and PreferenceScreen.getSharedPreferences() does, but according to the source code, they are identical.
PreferenceScreen:
public SharedPreferences getSharedPreferences() {
if (mPreferenceManager == null) {
return null;
}
return mPreferenceManager.getSharedPreferences();
}
So the PreferenceManger and PreferenceScreen are different entities, but the SharedPreference those method return should be the same object, since PreferenceScreen calls the method from PreferenceManager. I hope that is the answer you've been seeking.
If you have a choice, go with PreferenceManager.getSharedPreferences(), it's more obvious and one fewer method call internally.
Fun fact:
PreferenceFragment:
public PreferenceManager getPreferenceManager() {
return mPreferenceManager;
}
public PreferenceScreen getPreferenceScreen() {
return mPreferenceManager.getPreferenceScreen();
}
The first one gets the shared preferences from the PreferenceManager. The second one, from the PreferenceScreen, that inherits this method from Preference class.
I think this is not a functional difference, because both return probably the same instance of the SharedPreferences objects, but I think it's clearer to use the first one (using PreferenceManager instead of PreferenceScreen).
PreferenceScreen see domentation here
PreferenceScreen class can appear in two places:
When a PreferenceActivity points to this, it is used as the root and
is not shown (only the contained preferences are shown).
When it appears inside another preference hierarchy, it is shown and
serves as the gateway to another screen of preferences (either by
showing another screen of preferences as a Dialog or via a
startActivity(android.content.Intent) from the getIntent()). The
children of this PreferenceScreen are NOT shown in the screen that
this PreferenceScreen is shown in. Instead, a separate screen will be
shown when this preference is clicked.
PreferenceManager see documentation here:
Difference :
getPreferenceManager () returns the current preference manager associated with the fragment.
getPreferenceScreen () returns the root PreferenceScreen i.e. root preference screen used in the fragment from preference xml file(preferences.xml).
I'm trying to get and set a listPreference value from different activities and it's not working.
When I read and write it from my main activity, it only keeps whatever I write, so I'm assuming that I'm not targeting the listPreference correctly when I'm out of the activity because it's working inside my preference activity no problem.
I've seen some references on the developer website to CharSequence with getValue and getEntryValues but I haven't had luck getting them to work correctly either.
Here is my code for clicking a button and setting the listpreference value then it launches an intent to switch activities:
Main Activity, attempting to set the value of the listpreference to the first index value;
SharedPreferences settings = getSharedPreferences("PreferenceXML",
MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putString("ListPreferenceInXML", "1");
editor.commit();
String levelCheck = settings.getString("ListPreferenceInXML","1");
In my next activity I call read the value on launch to see which listPreference is active and it is always the number I write from the mains activity listed above. The problem is when I goto the actual Preference activity and it doesn't match or update when I change it on the ListPreference and launch the same activity from there (it still reads the value I set from the Main activity button)
code as follows for activity trying to read ListPreference:
SharedPreferences settings = getSharedPreferences("PreferenceXML",
MODE_PRIVATE);
Toast.makeText(this, settings.getString("ListPreferenceInXML","1"), 1000).show();
So I finally figured it out, the problem was with the way I was calling the preferences. Instead of calling the preferences like this, in both cases;
SharedPreferences settings = getSharedPreferences("PreferenceXML",
MODE_PRIVATE);
Call them like this:
SharedPreferences settings =
PreferenceManager.getDefaultSharedPreferences(getBaseContext());
I'm not sure if there is a step missing out of the first way of calling the preferences but this 2nd way worked like a champ.