I am implementing the Settings for my android app through the PreferenceFragment.
My android:summary for the different Preferences should display the current value at all times therefore I have read through severals posts and the official documentation.
Although I got it working technically my solution seems kind of hacky and I am now searching for best practice since I found no good source on how it is meant to be properly implemented.
For example I implemented onSharedPreferenceChanged to listen for changes and to update the UI, but after every restart of the PreferenceFragment, the initial android:summary is shown again. To solve this I added this to the onCreate
// display current value in the UI
EditTextPreference editText = (EditTextPreference) findPreference("serverAddress");
editText.setSummary(editText.getText());
Is this is how it is supposed to be done or am I misunderstanding something ?
Full Code:
public class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
public static final String KEY_PREF_SERVER_ADDRESS = "serverAddress";
public static final String KEY_PREF_GENDER = "gender";
public SettingsFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle saveInstanceState) {
super.onCreate(saveInstanceState);
//Load the preferences from the XML file
addPreferencesFromResource(R.xml.preferences);
// display current value in the UI
EditTextPreference editText = (EditTextPreference) findPreference("serverAddress");
editText.setSummary(editText.getText());
}
// Listen for settings changes and update the UI
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals(KEY_PREF_SERVER_ADDRESS)) {
Preference serverAddressPref = findPreference(key);
//Set UI to display updated summary
serverAddressPref.setSummary(sharedPreferences.getString(key, ""));
}
if (key.equals(KEY_PREF_GENDER)) {
Preference serverAddressPref = findPreference(key);
//Set UI to display updated summary
serverAddressPref.setSummary(sharedPreferences.getString(key, ""));
}
}
#Override
public void onResume() {
super.onResume();
getPreferenceScreen().getSharedPreferences()
.registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onPause() {
super.onPause();
getPreferenceScreen().getSharedPreferences()
.unregisterOnSharedPreferenceChangeListener(this);
}
}
Related
I'm trying to get my Android app's initial screen to update a TextView whenever a SharedPreference is changed in the settings menu, but I'm not sure exactly where to go from here.
This is a method that I added to my initial screen code to see if it would change when the preference was changed in the settings, but it never gets called according to my debugging efforts. Other parts of our application (mainly the search function) call this successfully.
public class initialScreen extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_initial_screen);
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key){
String nameOfPref = "test";
if (key.equals("instance")){
nameOfPref = sharedPreferences.getString("instance","test");
}
TextView tv = (TextView) findViewById(R.id.title);
tv.setText(nameOfPref);
}
// ... plus some other StartActivity(intent) methods that don't matter here
}
Which the preference is set by a different class like this:
public class mySettingsFragment extends PreferenceFragmentCompat {
#Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.preferences, rootKey);
}
}
I guess I'm trying to figure out how to make my initial screen dynamic and 'always listening' for that preference to change.
I am new to creating PreferenceActivity. My question is how to enable and disable option in preference screen by changing other preference?
My prefs.xml:
<ListPreference
android:entries="#array/units"
android:entryValues="#array/lunits"
android:key="listUnits"
android:summary="Units schosssing"
android:title="Units" android:defaultValue="C"/>
<ListPreference
android:entries="#array/palette"
android:entryValues="#array/lpalette"
android:key="listpalette"
android:summary="Palette schosssing"
android:title="Palette"
android:defaultValue="1"/>
In the listUnits there are 2 options, Celsius and Fahrenheit, so if user selects Celsius the listpalette should get enabled, and if user selects Fahrenheit becomes disabled, how can I do this?
My settings activity:
public class SettingsActivity extends PreferenceActivity
{
#Override
protected void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction().replace(android.R.id.content, new MyPreferenceFragment()).commit();
}
public static class MyPreferenceFragment extends PreferenceFragment
{
#Override
public void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.prefs);
}
}
}
This code may be useful to you. Can take as reference.
First take instance of both of the ListPreference and apply this method.
ListPreference mlistUnits, mlistPalette;
mlistUnits= (ListPreference)findPreference("listUnits");
mlistPalette= (ListPreference)findPreference("listpalette");
mlistUnits.setEnable(false);
mlistPalette.setEnabled(true);
and use below listner
OnPreferenceChangeListener listener = new OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
// newValue is the value you choose
return false;
}
};
apply listener to ListPreference
mlistPalette.setOnPreferenceChangeListener(listener);
Firstly you can set default value for your listUnits listpreference to celcius or Fahrenheit ,according this you can make enable-disable your second listpreference.
Now when changing your Preference by selecting anyone of them you can follow below procedure.
1) implement OnSharedPreferenceChangeListener in your MyPreferenceFragment class and override the method onSharedPreferenceChanged
2) Code like below in your method
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
// TODO Auto-generated method stub
if (key.equals("listUnits")) {
final String value = sharedPreferences.getString(key, "");
Preference Pref_cec=findPreference("listpalette");
if (value.equals("celcius")) {
wallpaperPref_admin.setEnabled(true);
}else{
wallpaperPref_admin.setEnabled(false);
}
}
}
Hope it will Help. Let me know if anything missing in my post.
As your second list is evaluated on basic of first list, what you may do
Look for preference click on the First list, get the value of preference clicked.
Using this value simply enable/disable your second list.
I am programming an application that uses SharedPreferences, one of them was a date, so I end up creating an Preference with and Intent so this acts like a button to another Activity on wich the user can select a date and time from pickers and stored the value as a String on my SharedPreferences, so far so good.
However, I want my "Preference button" to load that String into it's Summary property implementing the OnSharedPreferenceChangeListener, I have been able to do it for my EditTextPreference objects, here's my code so far:
public class SettingsActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener {
// DECLARATION OF USED OBJECTS
EditTextPreference userId;
EditTextPreference userName;
EditTextPreference hospital;
Preference dateTime;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.activity_preferences);
//LOAD SHARED PREFERENCES
SharedPreferences getData = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
//ASSING EACH DECLARED CONTROL A PREFERENCE
userId = (EditTextPreference) getPreferenceScreen().findPreference("pref_userId");
userName = (EditTextPreference) getPreferenceScreen().findPreference("pref_username");
hospital = (EditTextPreference) getPreferenceScreen().findPreference("pref_hospital");
dateTime = (Preference) getPreferenceScreen().findPreference("pref_dateTime");
}
#Override
protected void onPause() {
// STOPS MY LISTENER WHEN A KEY CHANGES
super.onPause();
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
}
#Override
// SETS UP MY LISTENER WHEN A KEY CHANGES
protected void onResume() {
super.onResume();
// LOADS SHARED PREFERENCES INTO THE PREFERENCES SUMMARIES
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
userId.setSummary(sharedPreferences.getString("pref_userId", ""));
userName.setSummary(sharedPreferences.getString("pref_username", ""));
hospital.setSummary(sharedPreferences.getString("pref_hospital", ""));
dateTime.setSummary(sharedPreferences.getString("pref_dateTime", ""));
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
//REFRESHES THE SUMMARIES WHEN A PREFERNECE IS CHANGED
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals("pref_userId")) {
userId.setSummary(sharedPreferences.getString(key, ""));
}else
if (key.equals("pref_username")) {
userName.setSummary(sharedPreferences.getString(key, ""));
}else
if (key.equals("pref_hospital")) {
hospital.setSummary(sharedPreferences.getString(key, ""));
}else
if (key.equals("pref_dateTime")) {
dateTime.setSummary(sharedPreferences.getString(key, ""));
}
}
This code does not generate any errors on Eclipse so it will allow me to test it but I get the app will just stop unexpectedly when I try to go into my PreferenceActivity
Error is on the OnResume and/or onSharedPreferenceChanged methods, any ideas on a workaround so I can display my saved SharedPreference on this Preference Summary by using this implement of PreferenceActivity or should be using another approch (Keeping in mind I have a min of API8). Thanks guys any help will be really appreaciated.
I am having a few issues with updating the summary line in the SharedPreferences as a preference changes. I have a registered OnSharePreferenceChangeListener in the onResume(), and an unregister of the same in the onPause().
The listener is functioning, and I am able to use the onSharedPreferenceChanges() method. The issue I am having is being able to retrieve the preference there so that I can call setSummary(). I am in Ice Cream Sandwich, and it appears as though the findPreference(key) method is deprecated. So:
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Preference pref = findPreference(key);}
is not functioning, and actually returns null for pref. From the examples I have seen, you need to get a preference to call setSummary() on it, and ideas?
You shouldn't use an onSharedPreferenceChangedListener for this.
Instead, use something similar to this.
ListPreference myPreference = (ListPreference) findPreference("preference_key");
myPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (((String)newValue).equals("some_value")) {
preference.setSummary("my summary");
}
}
});
findPreference is not deprecated, but rather you shouldn't be using a PreferenceActivity (that is deprecated). If you only need to support Android 3.0+ then you should switch to PreferenceFragment's, the new method. If you need to support Android 2.1+ then it is fine and you can ignore the warnings.
I have been trying to use PreferenceFragment in my code, and I was also seeing findPreference(key) return null. The sample code on the Settings documentation page for using OnSharedPreferenceChangeListener hasn't been fully updated for PreferenceFragment and you'll crash with NullPointerException if you use it verbatim.
I finally figured it out: You have to find the Preference via the PreferenceFragment because of course that's where the preferences are now. Obvious in hindsight. Something like this:
public class SettingsActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener
{
protected SettingsFragment settingsFragment;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
settingsFragment = new SettingsFragment();
getFragmentManager().beginTransaction().replace(android.R.id.content, settingsFragment).commit();
}
// ...
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals("your_key")) {
String newValue = sharedPreferences.getString(key, "");
settingsFragment.findPreference(key).setSummary(newValue);
}
}
}
I want to know if there is a way to check what someone is entering on the shared prefs/settings screen for validation. The user touches the Ip enter options, an edittext dialog pops up and I am trying to restrict what they can enter to something like a standard IP address(ie. 0-255.0-255.0-255.0-255) I have looked in numerous online forums and saw examples of different things with REGEX and patterns and this is what I have so far, but absolutely nothing is happening....Can anyone help me out? I would greatly appreciate it!
public class PrefsActivity extends PreferenceActivity implements
OnSharedPreferenceChangeListener
{
private EditTextPreference ipTextBox;
private String whatWasTyped;
private String previousText = "";
private Editor myEditor;
final Pattern IP_ADDRESS = Pattern
.compile("^((1\\d{2}|2[0-4]\\d|25[0-5]|\\d?\\d)\\.){3}(?:1\\d{2}|2[0-4]\\d|25[0-5]|\\d?\\d)$");
private String IP_FROM_PREFS = "ipAddressPref";
SharedPreferences prefs;
#Override
/**
* The onCreate method handles thing when starting this activity,
* mainly display the activity_settings.xml.
*/
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// pattern for IP address validation
addPreferencesFromResource(R.layout.activity_settings);
// prefs.registerOnSharedPreferenceChangeListener(this);
prefs = PreferenceManager.getDefaultSharedPreferences(this);
// Get a reference to the preferences
ipTextBox = (EditTextPreference) getPreferenceScreen().findPreference(
IP_FROM_PREFS);
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key)
{
// check prefs value for IP.
if (key.equals(IP_FROM_PREFS))
{
whatWasTyped = prefs.getString(IP_FROM_PREFS, "");
CharSequence s = whatWasTyped;
if (IP_ADDRESS.matcher(s).matches())
{
previousText = s.toString();
myEditor = prefs.edit();
myEditor.putString(IP_FROM_PREFS, previousText);
myEditor.commit();
} else
{
//if the format does not match, put up an error message
// or something.
}
}
}
#Override
protected void onResume()
{
super.onResume();
// Setup the initial values
// mCheckBoxPreference.setSummary(sharedPreferences.getBoolean(key,
// false) ? "Disable this setting" : "Enable this setting");
// mListPreference.setSummary("Current value is " +
// sharedPreferences.getValue(key, ""));
// Set up a listener whenever a key changes
getPreferenceScreen().getSharedPreferences()
.registerOnSharedPreferenceChangeListener(this);
previousText = prefs.getString(IP_FROM_PREFS, "");
}
#Override
protected void onPause()
{
super.onPause();
// Unregister the listener whenever a key changes
getPreferenceScreen().getSharedPreferences()
.unregisterOnSharedPreferenceChangeListener(this);
}
}
Since this is something created on the shared prefs screen, there are no button id, etc...
Just writing
whatWasTyped.replace(s, previousText);
will not assign the the previousText to the SharedPreference you need to assign it back to the shared preference and commit.