PreferenceActivity with custom functionality


SDK Version: 
M3

As we previously desribed in PreferenceActivity Basics a preferences screen with basic features can be done with minimal work, only using XML. Now we will inplement some functionality beyond the base ones, this will require some coding in addition to the XML definition.

We will display the actual value in each preferences summary field, like this:

The base XML will be the same as in the previous example, but we dont need to fill summary fields, they will be filled dinamically.

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
  3.         android:title="Settings">
  4.         <EditTextPreference android:title="Name"
  5.                 android:inputType="text"
  6.                 android:key="name" android:persistent="true" android:defaultValue="" />
  7.                
  8.         <EditTextPreference android:title="Password"
  9.                 android:inputType="textPassword"
  10.                 android:key="password" android:persistent="true" android:defaultValue="" />
  11.  
  12.         <CheckBoxPreference android:title="Auto login"
  13.          android:key="autostart" android:defaultValue="true" />
  14. </PreferenceScreen>

First when the Activity is created, we must dinamically set the summary fields starting value, like this:

Second, we must set a listener on each preference change, to update the value when it changes.
For this, the PreferenceActivity class will implement OnSharedPreferenceChangeListener and we will register the listener in onResume() and unregister it in onPause() and handle the changes in the onSharedPreferenceChangedlistener() method.

We take different actions depending on field type. For example we can not directly output the value of a checkbox, and we dont want to display passwords.

  1. public class Settings extends PreferenceActivity implements
  2. OnSharedPreferenceChangeListener {
  3.   @Override
  4.   protected void onCreate(Bundle savedInstanceState) {
  5.     super.onCreate(savedInstanceState);
  6.     PreferenceManager.setDefaultValues(this, R.xml.settings, false);
  7.     addPreferencesFromResource(R.xml.settings);
  8.  
  9.     SharedPreferences sp = getPreferenceScreen().getSharedPreferences();
  10.  
  11.     Preference name = (Preference) findPreference("name");
  12.     name.setSummary(sp.getString("name", ""));
  13.  
  14.     Preference password = (Preference) findPreference("password");
  15.     password.setSummary(sp.getString("password", "").replaceAll(".","*"));
  16.            
  17.     CheckBoxPreference autostart = (CheckBoxPreference) findPreference("autostart");
  18.     if(autostart.isChecked())
  19.       autostart.setSummary("On");
  20.     else
  21.       autostart.setSummary("Off");
  22.   }
  23.  
  24.   @Override
  25.   protected void onPause() {
  26.     getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
  27.     finish();
  28.     super.onPause();
  29.   }
  30.  
  31.   protected void onResume() {
  32.     super.onResume();
  33.     getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
  34.   }
  35.  
  36.   public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
  37.     Preference pref = findPreference(key);
  38.     if (pref instanceof EditTextPreference) {
  39.       EditTextPreference etp = (EditTextPreference) pref;
  40.       if(pref.getKey().equals("password")){
  41.         pref.setSummary(etp.getText().replaceAll(".","*"));
  42.       }else{
  43.          pref.setSummary(etp.getText());
  44.       }
  45.     }else if(pref instanceof CheckBoxPreference){
  46.       if(((CheckBoxPreference)pref).isChecked())
  47.       pref.setSummary("On");
  48.     else
  49.       pref.setSummary("Off");
  50.     }
  51.   }
  52. }