For almost any application we need to provide some settings in order to enable users have some level of control over how the application works. Android has provided a standard mechanism to show, save and manipulate user's preferences. PreferenceActivity class is the standard Android Activity to show Preferences page, it contains a bunch of Preference class instances which use SharedPreference
class to save and manipulate corresponding data.There are different types of Preferences Available in Preference package, and if you need something more you can extend Preference class and create your own Preference type. in this article we will go through predefined Preference types in Android and I'm also going to implement a custom Preference type to see how that works.
Our Preferences page is gonna look like this :
as you can see we have two section in our preferences page , "First Category" which contains two options and "Second Category" which contains three options.
here is our Activity which produces this page :
pretty simple, isn't it? actually it's supposed to be simple and easy thanks to PreferenceActivity which takes care of pretty much anything. as i said PreferenceActivity renders instances of Preference class which in this example
have defined in preferences.xml file under res/xml directory:
First thing i wanna talk about is dependency, Dependency helps you to disable/enable some Preferences based on the status of another preference. in this example we have three preferences dependent on the first preference so if we disable the first option all dependent options will become uneditable.
if we select the second option we will see something like this :
ListPreference tag has two attribute which is used to populate its content; android:entries which refers to an array of labels and android:entryValues which is also an array that represent the actual value of entries, this value will be saved when each entry gets selected. as you can see I've used "@array/" indicator for these two attribute, it means we have our data in arrays.xml file under res/values directory and here is its content :
you sometimes want to show a set of Preferences in a different window, to do so you just need to wrap all those Preferences in a PreferenceScreen tag, just like what I've done for "Advanced Options" in this example so when user presses this option we will see something like this :
The last Predefined Preference type I'm gonna talk about is EditTextPreference, when user presses one of these type of Preferences, a dialog with a Text Field pops up and let the user enter a text. I used a EditTextPreference for the last option in this example and you can see here how it's gonna look like after being pressed :
So far we've seen what functionality we have already got in our hand which would fulfill our needs in most circumstances but what if we need something that is not already there? Not a big deal... we'll just need to roll up our sleeves and implement our own Preference type.
I've developed a simple custom preference type which shows a seekbar and stores an Integer value each time user moves the seekbar. you can see how it looks like in the first picture above.
here is our SeekBarPreference class source code :
In all examples I've come across about custom preferences, an XML layout file has been used to create the preference view, so I thought it would be a good idea not to used XML and go programatically and actually it was a good opportunity for a person like me who had always used XML for creating GUIs in Android to go through an alternative way.
anyway onCreateView() method of Preference class is responsible to return a View to be shown by PereferenceActivity,we override this method to make our own custom view, in Preference class documentation we've been asked to return a ViewGroup with "widget_frame" as its ID, that's what I've done and you should do if you want to do something like this.
Another thing to remember is that if you're willing to let clients of this preference type set Listeners and get notified when the status of preference changes you have to call callChangeListener() method before saving new value, this method will invoke the listener callback method and return the result, if client is happy with new value and operation can be carried out the result will be true, otherwise it will be false. Don't forget to call notifyChanged() method once you have saved new value of preference, though I'd forgotten to do so and it was working like a charm ;)
I've also used both Preference class's persistInt() method and Editor class's putInt() method to store data in this example to show different ways that it can be done.
And here is a simple Activity which retrieves preferences values and show them in a textview :