Lecture Series on Android Programming Lecturer: Prof.Luqun Li Teaching Assistants: Fengyou Sun, Haijun Yang, Ting Sun Chapter 11 Managing and Organizing preferences
Shanghai Normal University 2 Contents 1 1 Defining preferences 2 2 Displaying Preferences 3 3 Reading Preferences 4 4 Building a custom preference
Shanghai Normal University 3 Overview If you want to provide settings for y our app, you should use Android's P reference APIs to build an interfac e that's consistent with the user exp erience in other Android apps (inclu ding the system settings).
Shanghai Normal University 4 Overview Settings are built using various subc lasses of the Preference class that you declare in an XML file A Preference object is the building block for a single setting. Each Preference appears as an ite m in a list and provides the appropri ate UI for users to modify the settin g.
Shanghai Normal University 5 Overview Each Preference you add has a correspo nding key-value pair that the system use s to save the setting in a default Shared Preferences file for your app's settings. When the user changes a setting, the sys tem updates the corresponding value in t he SharedPreferences file for you. The only time you should directly interact with the associated SharedPreferences file is when you need to read the value in order to determine your app's behavior b ased on the user's setting.
Shanghai Normal University 6 Value saved in SharedPreferences Boolean Float Int Long String String Set
Shanghai Normal University 7 Display the list settings On Android older than 3.0 (API level 10 and lower), you must build the a ctivity as an extension of the Prefe renceActivity class. On Android 3.0 and later, you shoul d instead use a traditional Activity that hosts a PreferenceFragment. You can also use PreferenceActivity to cre ate a two-pane layout for large screens whe n you have multiple groups of settings.
Shanghai Normal University 8 Preferences Every setting for your app is repres ented by a specific subclass of the P reference class. Each subclass includes a set of core properties that allow you to specify things such as a title for the setting and the default value. Each subclass also provides its own specialized properties and user inter face.
Shanghai Normal University 9 Common preferences CheckBoxPreference Shows an item with a checkbox for a setting that is either enabled or disabled. The saved value is a boolean (true if it's checked). ListPreference Opens a dialog with a list of radio buttons. T he saved value can be any one of the suppo rted value types (listed above). EditTextPreference Opens a dialog with an EditText widget. The saved value is a String.
Shanghai Normal University 10 Defining Preferences in XML Define your list of settings in XML w ith a hierarchy of Preference objec ts Save the XML file in the res/xml/ dir ectory Name the file anything you want, pr eferences.xml
Shanghai Normal University 11 Defining Preferences in XML The root node for the XML file must be a elemen t. Within this element is where you ad d each Preference. Each child within the element appears as a sing le item in the list of settings.
Shanghai Normal University 12 Defining Preferences in XML <CheckBoxPreference android:key="pref_sync" android:defaultValue="true" /> <ListPreference android:dependency="pref_sync" android:key="pref_syncConnectionType" s" ult" />
Shanghai Normal University 13 Defining Preferences in XML
Shanghai Normal University 14 Defining Preferences in XML
Shanghai Normal University 15 Creating setting groups A group of related settings can be p resented in one of two ways: Using titles Using subscreens You can use one or both of these grouping t echniques to organize your app's settings.
Shanghai Normal University 16 Using titles If you want to provide dividers with headings between groups of setting s, place each group of Preference o bjects inside a PreferenceCategory.
Shanghai Normal University 17 Using titles <PreferenceCategory android:key="pref_key_storage_settings"> <CheckBoxPreference android:key="pref_key_auto_delete" android:defaultValue="false"... /> <Preference android:key="pref_key_sms_delete_limit" android:dependency="pref_key_auto_delete" /> <Preference android:key="pref_key_mms_delete_limit" android:dependency="pref_key_auto_delete" />...
Shanghai Normal University 18 Using titles
Shanghai Normal University 19 Using subscreens If you want to place groups of settin gs into a subscreen, place the group of Preference objects inside a Prefer enceScreen.
Shanghai Normal University 20 Using subscreens <PreferenceScreen android:key="button_voic _category_key" android:persistent="false"> <ListPreference android:key="button_voic _provider_key" /> <PreferenceScreen android:key="button_voic _setting_key" android:persistent="false">... <RingtonePreference android:key="button_voic _ringtone_key" android:ringtoneType="notification"... />......
Shanghai Normal University 21 Using subscreens
Shanghai Normal University 22 Using intents In some cases, you might want a pr eference item to open a different ac tivity instead of a settings screen, s uch as a web browser to view a web page. To invoke an Intent when th e user selects a preference item, ad d an element as a child of the corresponding ele ment.
Shanghai Normal University 23 Using intents <intent android:action="android.int ent.action.VIEW" android:data=" com" />
Shanghai Normal University 24 Using intents android:action The action to assign, as per the setAction() method. android:data The data to assign, as per the setData() method. android:mimeType The MIME type to assign, as per the setType() met hod. android:targetClass The class part of the component name, as per the s etComponent() method. android:targetPackage The package part of the component name, as per th e setComponent() method.
Shanghai Normal University 25 Contents 1 1 Defining preferences 2 2 Displaying Preferences 3 3 Reading Preferences 4 4 Building a custom preference
Shanghai Normal University 26 Creating a Preference Activity Extend the PreferenceActivity cla ss, which automatically persists the settings associated with each Prefe rence when the user makes a chan ge. Call addPreferencesFromResourc e() during the onCreate() callback instead of loading a layout of views call
Shanghai Normal University 27 Creating a Preference Activity public class SettingsActivity extends Pref erenceActivity public void onCreate(Bundle savedInstan ceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.pref erences); }
Shanghai Normal University 28 Using Preference Fragments If you're developing for Android 3.0 (API level 11) and higher, you shoul d use a PreferenceFragment to di splay your list of Preference object s. Use PreferenceFragment to contr ol the display of your settings instea d of PreferenceActivity when poss ible.
Shanghai Normal University 29 Implementation of PreferenceFragment public static class SettingsFragment extends Pre ferenceFragment public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Load the preferences from an XML resource addPreferencesFromResource(R.xml.preference s); }... }
Shanghai Normal University 30 Add fragment Activity public class SettingsActivity extends Activity protected void onCreate(Bundle savedInstanceS tate) { super.onCreate(savedInstanceState); // Display the fragment as the main content. getFragmentManager().beginTransaction().repl ace(android.R.id.content, new SettingsFragment ()).commit(); }
Shanghai Normal University 31 Setting Default Values Specify a default value for each Pref erence object in your XML file using the android:defaultValue Then, call setDefaultValues() in a ny other activity (onCreate()) thro ugh which the user may enter your application for the first time
Shanghai Normal University 32 Setting Default Values <Che ckBoxPreference android:defaultValue="t rue"... /> <ListPreference ult"... />
Shanghai Normal University 33 Setting Default Values PreferenceManager.setDefaultV alues(this, R.xml.advanced_pref erences, false); Arguments : Your application Context. The resource ID for the preference XML file f or which you want to set the default values. A boolean indicating whether the default val ues should be set more than once.
Shanghai Normal University 34 Using Preference Headers Separate each group of settings into se parate instances of PreferenceFragm ent. That is, each group of settings nee ds a separate XML file. Create an XML headers file that lists ea ch settings group and declares which fr agment contains the corresponding list of settings. Extend the PreferenceActivity class t o host your settings. Implement the onBuildHeaders() call back to specify the headers file.
Shanghai Normal University 35 Using Preference Headers
Shanghai Normal University 36 Creating the headers file <header android:fragment="com.example.prefs.SettingsActivity $SettingsFragmentOne" /> <header android:fragment="com.example.prefs.SettingsActivity $SettingsFragmentTwo" > <extra android:name="someKey" android:value="someHeaderValue" />
Shanghai Normal University 37 Pass key-value pairs to the fragmen t in a Bundle Retrieve the arguments by calling g etArguments() Specify which preferences XML file t he fragment should load from the s ame subclass of PreferenceFragm ent
Shanghai Normal University 38 public static class SettingsFragment extends PreferenceFr agment public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); String settings = getArguments().getString("settings"); if ("notifications".equals(settings)) { addPreferencesFromResource(R.xml.settings_wifi); } else if ("sync".equals(settings)) { addPreferencesFromResource(R.xml.settings_sync); }
Shanghai Normal University 39 Displaying the headers public class SettingsActivity extends PreferenceActivity public void onBuildHeaders(List target) { loadHeadersFromResource(R.xml.pr eference_headers, target); }
Shanghai Normal University 40 Contents 1 1 Defining preferences 2 2 Displaying Preferences 3 3 Reading Preferences 4 4 Building a custom preference
Shanghai Normal University 41 Reading Preferences PreferenceManager.getDefaultShare dPreferences() Return the SharedPreferences object SharedPreferences sharedPref = Preferen ceManager.getDefaultSharedPreferences (this); String syncConnPref = sharedPref.getStri ng(SettingsActivity.KEY_PREF_SYNC_CO NN, "");
Shanghai Normal University 42 Listening for preference changes Implement the SharedPreference. OnSharedPreferenceChangeList ener interface Register the listener for the Shared Preferences object by calling regi sterOnSharedPreferenceChange Listener() The interface has only one callback method, onSharedPreferenceChanged()
Shanghai Normal University 43 Listening for preference changes public class SettingsActivity extends PreferenceActivity im plements OnSharedPreferenceChangeListener { public static final String KEY_PREF_SYNC_CONN = "pref_s yncConnectionType";... public void onSharedPreferenceChanged(SharedPreferenc es sharedPreferences, String key) { if (key.equals(KEY_PREF_SYNC_CONN)) { Preference connectionPref = findPreference(key); // Set summary to be the user-description for the selecte d value connectionPref.setSummary(sharedPreferences.getString (key, "")); }
Shanghai Normal University 44 Listening for preference changes Register your SharedPreferences. OnSharedPreferenceChangeList ener during the onResume() callb ack Unregister during the onPause() c allback
Shanghai Normal University 45 Listening for preference protected void onResume() { super.onResume(); getPreferenceScreen().getSharedPreferences(). registerOnSharedPreferenceChangeListener(thi s); protected void onPause() { super.onPause(); getPreferenceScreen().getSharedPreferences(). unregisterOnSharedPreferenceChangeListener(t his); }
Shanghai Normal University 46 Contents 1 1 Defining preferences 2 2 Displaying Preferences 3 3 Reading Preferences 4 4 Building a custom preference
Shanghai Normal University 47 Building a Custom Preference Specify the user interface that appears w hen the user selects the settings. Save the setting's value when appropriat e. Initialize the Preference with the curren t (or default) value when it comes into vi ew. Provide the default value when requested by the system. If the Preference provides its own UI (s uch as a dialog), save and restore the st ate to handle lifecycle changes (such as when the user rotates the screen).
Shanghai Normal University 48 Specifying the user interface Extend DialogPreference to show a dialog Call setDialogLayoutResourcs() during in the class constructor to sp ecify the layout for the dialog
Shanghai Normal University 49 Specifying the user interface public class NumberPickerPreference extends Di alogPreference { public NumberPickerPreference(Context context, AttributeSet attrs) { super(context, attrs); setDialogLayoutResource(R.layout.numberpicke r_dialog); setPositiveButtonText(android.R.string.ok); setNegativeButtonText(android.R.string.cancel); setDialogIcon(null); }... }
Shanghai Normal University 50 Saving the setting's value Save a value for the setting at any time by calling one of the Preference class's p ersist*() protected void onDialogClosed(boolean p ositiveResult) { // When the user selects "OK", persist th e new value if (positiveResult) { persistInt(mNewValue); }
Shanghai Normal University 51 Initializing the current value When the system adds your Prefere nce to the screen, it calls onSetInit ialValue() to notify you whether th e setting has a persisted value. The onSetInitialValue() method pas ses a boolean, restorePersistedVa lue, to indicate whether a value has already been persisted for the settin g.
Shanghai Normal University 52 Initializing the current protected void onSetInitialValue(boolean restore PersistedValue, Object defaultValue) { if (restorePersistedValue) { // Restore existing state mCurrentValue = this.getPersistedInt(DEFAULT _VALUE); } else { // Set default state from the XML attribute mCurrentValue = (Integer) defaultValue; persistInt(mCurrentValue); }
Shanghai Normal University 53 Providing a default value If the instance of your Preference class s pecifies a default value (with the android: defaultValue attribute), then the system calls onGetDefaultValue() when it inst antiates the object in order to retrieve th e protected Object onGetDefaultValue(Typ edArray a, int index) { return a.getInteger(index, DEFAULT_VAL UE); }
Shanghai Normal University 54 Saving and restoring state Implement the lifecycle callback me thods onSaveInstanceState() an d onRestoreInstanceState() State An object that implements the Parcelable int erface An object to define your state Preference.BaseSavedState
Shanghai Normal University 55 State pattern private static class SavedState extends BaseSavedState { // Member that holds the setting's value // Change this data type to match the type saved by your Preference int value; public SavedState(Parcelable superState) { super(superState); } public SavedState(Parcel source) { super(source); // Get the current preference's value value = source.readInt(); // Change this to read the appropriate data type }
Shanghai Normal University 56 State public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); // Write the preference's value // Change this to write the appropriate data type dest.writeInt(value); } // Standard creator object using an instance of this class public static final Parcelable.Creator CREATOR = new Parcelable.Creator () { public SavedState createFromParcel(Parcel in) { return new SavedState(in); } public SavedState[] newArray(int size) { return new SavedState[size]; } }; }
Shanghai Normal University 57 protected Parcelable onSaveInstanceState() { final Parcelable superState = super.onSaveInstanceState (); // Check whether this Preference is persistent (continually saved) if (isPersistent()) { // No need to save instance state since it's persistent, use superclass state return superState; } // Create instance of custom BaseSavedState final SavedState myState = new SavedState(superState); // Set the state's value with the class member that holds current setting value myState.value = mNewValue; return myState; }
Shanghai Normal University 58 protected void onRestoreInstanceState(Parcelable state) { // Check whether we saved the state in onSaveInstanceState if (state == null || !state.getClass().equals(SavedState.class)) { // Didn't save the state, so call superclass super.onRestoreInstanceState(state); return; } // Cast state to custom BaseSavedState and pass to superclass SavedState myState = (SavedState) state; super.onRestoreInstanceState(myState.getSuperState()); // Set this Preference's widget to reflect the restored state mNumberPicker.setValue(myState.value); }
Shanghai Normal University 59 Summary This document describes how to buil d your app settings using Preferen ce APIs. At last, you learned how to build a c ustom Preference.