Android Preferences
Preferences are an important part of an Android application. It is important to let the users have the choice to modify and personalize their application depending on their needs.
In the screenshots "custom" is spelled "costum". The typo is fixed in the code examples.
Android preferences can be set in two ways. You can create a preferences.xml file in the res/xml directory, or you can set the preferences from code.
The first example shows a preferences.xml file. Every preference needs to have a android:key value, that we call to get the preference's value. The android:title is the preference's title, and the android:summary is a summary about the preference. The android:defaultValue is the default value of the preference - fx. true or false.
Currently there are 5 different preference views:
- The CheckBoxPreference is a simple checkbox, that can return true or false.
- The ListPreference, which shows a radioGroup where only 1 item can be selected a time. The android:entries links to an array in the res/values/arrays, and the android:entryValues is an other array with the items to be returned.
- The EditTextPreference shows a dialog with an editText view. This returns a String.
- The RingtonePreference shows a radioGroup that shows the ringtones.
- The Preference is a custom preference. This works like a Button.
- The PreferenceScreen is a screen with preferences. When you have a PreferenceScreen inside an other PreferenceScreen, it simply opens a new screen with other preferences.
- The PreferenceCategory is a category with preferences.
-
Custom preference
-
Edit Text Preference
-
List Preference
-
Ringtone Preference
-
Preference Screen
This is an example on the preferences.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | <?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <PreferenceCategory android:title="First Category"> <CheckBoxPreference android:title="Checkbox Preference" android:defaultValue="false" android:summary="This preference can be true or false" android:key="checkboxPref" /> <ListPreference android:title="List Preference" android:summary="This preference allows to select an item in a array" android:key="listPref" android:defaultValue="digiGreen" android:entries="@array/listArray" android:entryValues="@array/listValues" /> </PreferenceCategory> <PreferenceCategory android:title="Second Category"> <EditTextPreference android:name="EditText Preference" android:summary="This allows you to enter a string" android:defaultValue="Nothing" android:title="Edit This Text" android:key="editTextPref" /> <RingtonePreference android:name="Ringtone Preference" android:summary="Select a ringtone" android:title="Ringtones" android:key="ringtonePref" /> <PreferenceScreen android:key="SecondPrefScreen" android:title="Second PreferenceScreen" android:summary="This is a second PreferenceScreen"> <EditTextPreference android:name="An other EditText Preference" android:summary="This is a preference in the second PreferenceScreen" android:title="Edit text" android:key="SecondEditTextPref" /> </PreferenceScreen> <Preference android:title="Custom Preference" android:summary="This works almost like a button" android:key="customPref" /> </PreferenceCategory> </PreferenceScreen> |
To show the preference screen, we create a class which extends PreferenceActivity. This is an example on the preference class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | package org.kaloer.preferenceexample; import android.app.Activity; import android.content.SharedPreferences; import android.os.Bundle; import android.preference.Preference; import android.preference.PreferenceActivity; import android.preference.Preference.OnPreferenceClickListener; import android.widget.Toast; public class Preferences extends PreferenceActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.preferences); // Get the custom preference Preference customPref = (Preference) findPreference("customPref"); customPref .setOnPreferenceClickListener(new OnPreferenceClickListener() { public boolean onPreferenceClick(Preference preference) { Toast.makeText(getBaseContext(), "The custom preference has been clicked", Toast.LENGTH_LONG).show(); SharedPreferences customSharedPreference = getSharedPreferences( "myCustomSharedPrefs", Activity.MODE_PRIVATE); SharedPreferences.Editor editor = customSharedPreference .edit(); editor.putString("myCustomPref", "The preference has been clicked"); editor.commit(); return true; } }); } } |
We can call this activity when we click a button:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button prefBtn = (Button) findViewById(R.id.prefButton); prefBtn.setOnClickListener(new OnClickListener() { public void onClick(View v) { Intent settingsActivity = new Intent(getBaseContext(), Preferences.class); startActivity(settingsActivity); } }); } |
To read these preferences from code, we should create a getPrefs() method, which we can call in the onStart() method. When we call it in the onStart() method instead of onCreate(), we can be sure that the preferences load when we have set them and returned to our main activity,
The getPrefs() method could look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | boolean CheckboxPreference; String ListPreference; String editTextPreference; String ringtonePreference; String secondEditTextPreference; String customPref; private void getPrefs() { // Get the xml/preferences.xml preferences SharedPreferences prefs = PreferenceManager .getDefaultSharedPreferences(getBaseContext()); CheckboxPreference = prefs.getBoolean("checkboxPref", true); ListPreference = prefs.getString("listPref", "nr1"); editTextPreference = prefs.getString("editTextPref", "Nothing has been entered"); ringtonePreference = prefs.getString("ringtonePref", "DEFAULT_RINGTONE_URI"); secondEditTextPreference = prefs.getString("SecondEditTextPref", "Nothing has been entered"); // Get the custom preference SharedPreferences mySharedPreferences = getSharedPreferences( "myCustomSharedPrefs", Activity.MODE_PRIVATE); customPref = mySharedPreferences.getString("myCusomPref", ""); } |
Remember to add the following tag in your androidmanifest.xml file and add a new string item with the name "set_preferences" with the preference screen's title, for example "Preferences"
1 2 3 4 | <activity android:name=".Preferences" android:label="@string/set_preferences"> </activity> |
This is the final result
-
The main activity screen
-
The preference activity
Popular blog posts
-
Android Preferences
Preferences are an important part of an Android application. It is important to let the users have the choice to modify...
-
Incoming SMS Messages
During the development of version 1.3 of Kaloer Clock, I wanted to show an icon when a new sms message was received....
-
Permissions in Kaloer Clock
Android application security has recently become a focus of interest when talking about Android. A chinese developer...
Comments
You spelled "custom" wrong.
Great article!
Fantastic examples!
Thank you so much!
Great article - exactly what I was looking for.
Took me a while to figure out that listArray and listValues (mentioned under the ListPreference in preferences.xml) are actually two arrays that need to be defined in res/values/arrays.xml.
Could you please add your source code.
I am a newb and am having a hard time understanding the code.
Hi,
I'm sorry but I wrote the article for about a year ago, so unfortunately I don't have the source code anymore. But I'll provide one in every article I write in the future. Sorry!
Very clear, thanks!!
Thanks Kalor! This helped a lot.
niceee
thanks for the tutorial. Please how do you make the preference screen the first screen displayed when onCreate() is called.
Thank you
Manuel:
I'm not sure I understand your question. In the preference activity, the preferences are shown by calling
addPreferencesFromResource(R.xml.preferences);in onCreate().If you want the preference screen to be the first activity shown in your application, you will have to add the following to your android manifest file:
Thanks for a nice tutorial. I hope you can help me expand on this. I would like to add preferences to each item in a ListView. For example, say i had a list view of cars - i would like to be able to define individual preferences for each one of the cars in the list (i.e. make, model, color, etc...)
How can i do this? Everything i find on the web seems to point at a single set of preferences for an app, but i need to have multiple sets.
Thanks again for the tutorial, and any advice you can provide.
//Nick
If you want the preferences to be saved to your preferences file, you have to call:
getPreferenceManager().setSharedPreferencesName(preferences_file_name);
You should do this at the beginning of your PreferenceActivity's onCreate() method, right after you call super.onCreate() and right before you call addPreferencesFromResource()
Is it possible to set a backgroundimage on a PreferenceScreen?
I have tried the tag android:background="@drawable/some_background" which can be set in for example a LinearLayout XML, but it doesn't work in the PreferenceScreen.
The only way to do it (as far as I know) is to do it in code. In your PreferenceActivity you can call
getListView()to get the ListView. You can then set the background on this listview by callingsetBackgroundResource(int resource).F.eks. in the
onCreatemethod:getListView().setBackgroundResource(R.drawable.my_background)I believe the background image can be set on the root PreferenceScreen but it won't work on any nested screens.
If anyone knows a solution to this, I would love to know.
Do you know if it's possible to customize a preference screen (adding icones before text for example) ?
Well, it's not that easy. There is a discussion about it here
This is fantastic. The only thing that would make it better is if you showed how to define listArray and listValues so your code would compile without errors.
anyone please give me a source code about preferences like that..
i'm still confused, and my source code always get errors,,
T_T
To define the listArray and listValues create a new file in your project at this path: /res/values/array.xml
The contents of that file should be:
<?xml version="1.0" encoding="utf-8"?>
Let's try that again. The file contens should be:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="listArray">
<string-array name="listValues">
</resources>
Thanks Mads Kalør...
thanks geoff, but i still never got it, the code has already right but, when i press the preference button always appear force close on screen,, are them have 2 java file ?
In your res/values folder add a file called arrays.xml. Take a look at the documentation.
For example this xml file declares two arrays with 3 objects - one with the visible strings and another with the strings' IDs:
Oh i'm very thank you to Mads Kaloer and Geoff McGrath, the code has been work, its help me very much, thanks..
:D
Will be definitively using it in my application.
Thanks for this very well written post :)
I've been stuck on this for a whole night. The problem is that in the main .java file I have a variable "i" which goes to "i++" every millisecond and I have a Custom Option to reset it to 0 in the preferences .java. Now: every time I enter the preferences screen, i goes to 0 automatically and the related text is reset as well (I am checking if reset is selected /* with an alert - yes/no dialog */ with a boolean). Please, does anyone have any idea of what the problem might be?
P.S.: Thanks Mads, awesome tutorial!!!
Solved it. I don't know what was wrong, but I set the boolean to false in onCreate(), before setting it to true.
I was about to build the whole preferences-thing by myself until I found your page, I didn't think it could be that easy. Thanks very much, this really my day!!
Post new comment