Prerequisites:
-experience with widgets
-experience with intents and activities
-experience with XML layouts and resource files
In this Tutorial:
-a HelloWorld application that gets a custom message from the settings
-adding a preferences activity to your application
-adding menus to your activity from XML
Now, lets.getStarted()
First, create your project in eclipse(or whatever your current coding environment is) with a MainActivity and a main.xml (but don't touch those just yet).
Now, to add preferences to your app, we will need to do a few things:
1) Create a resource file named prefs.xml
2) Create and implement a PrefsActicity.java that will be be inflated by prefs.xml
3) Make a way to get to the Preference screen
Creating the Preferences
prefs.xml
Start by creating a PreferenceScreen resource file in /res/xml/

This is basically a layout for preference screens, it is where you will design your UI.
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<EditTextPreference
android:title="Custom Message 1"
android:summary="A message that you create"
android:key="custom_message_1" />
<CheckBoxPreference
android:title="Second Custom Message?"
android:summaryOn="There will be a second message."
android:summaryOff="There will not be a second message."
android:key="chkbox_second_custom_message" />
<EditTextPreference
android:title="Custom Message 2"
android:summary="A second message that you create"
android:key="custom_message_2"
android:dependency="chkbox_second_custom_message"/>
</PreferenceScreen>
EditTextPreference - The type of item in the preferences. This one brings up a dialog box for the user to enter text. (to see others, press < then Ctrl+Space)
CheckBoxPreference - The type of item in the preferences. When checked, it will display summaryON and will enable the items that depend on it. When unchecked, it will display summaryOff and will disable the items that depend on it.
dependency - Shows that whether the item's state (enabled or disabled) is dependent on whether the check box is checked or unchecked
title - The bold title that is displayed in the preferences.
summary - The smaller text under the title that describes the option.
key - A unique identifier for the preference item. This will be used to look up a preference.
PrefsActivity.java
Create the Preference Activity that will be inflated by prefs.xml
package com.hotTACOcheese.preferencestutorial;
import android.os.Bundle;//as usual
import android.preference.PreferenceActivity;//instead of a regular Activity
public class PrefsActivity extends PreferenceActivity{ //instead of a regular Activity
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.prefs);//instead of setContentView()
}
}
It's just slightly different from a regular Activity.
REMEMBER to add it to the manifest.
<activity
android:name=".PrefsActivity"
android:label="@string/title_prefs" />
Implementing the Preferences
menu.xml
Create menu.xml in /res/menu/
This is where we will create the menu that will call an intent to open the preferences.

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/item_prefs"
android:icon="@android:drawable/ic_menu_preferences"
android:title="@string/title_prefs" />
</menu>
item - A menu item that will be used in the MainActivity.java
icon - The icon that will be shown with the menu item (from android framework's drawables. Whole list of 'em)
id - If you don't know this, I would recommend pressing the back button right about now.
main.xml (already should know how to do this)
Go to the main.xml that is automatically generated by eclipse. Now we will set up the simple UI. Just three simple TextViews, the title has text, but the other two will be assigned in the future.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/title_message" />
<TextView
android:id="@+id/txtCustomMsg1"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/txtCustomMsg2"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
MainActivity.java
Open up the auto-generated main activity. This is where we will add the menu.
Time to import!
import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.view.MenuItem; import android.view.MenuInflater; import android.view.View; import android.widget.TextView; import android.widget.Toast; import android.view.Menu; import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.preference.PreferenceManager;
On to the body...
public class MainActivity extends Activity {
TextView txtMessage1;
TextView txtMessage2;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txtMessage1 = (TextView)this.findViewById(R.id.txtCustomMsg1);
txtMessage2 = (TextView)this.findViewById(R.id.txtCustomMsg2);
}
}
Pretty basic right now, I know.
Let's add the menu that we created earlier.
Start by writing a method that will load the options menu. It will only be called the first time that the user presses the menu button while at this activity.
//called when user first clicks menu button
@Override
public boolean onCreateOptionsMenu(Menu menu){
MenuInflater inflater = getMenuInflater();//create a MenuInflater to help use the menu that we already made in XML
inflater.inflate(R.menu.menu, menu);//inflate this menu with the XML resource that was created earlier
return true;//to allow method to be displayed
}
Now to write the method that will be called when an option in the menu is selected.
//called when an option is clicked
@Override
public boolean onOptionsItemSelected(MenuItem item){
switch(item.getItemId()){//decide which MenuItem was pressed based on its id
case R.id.item_prefs:
startActivity(new Intent(this, PrefsActivity.class));//start the PrefsActivity.java
break;
}
return true; //to execute the event here
}
Even though there is only one possible MenuItem that can be picked, it is still good practice to use a switch statement here in case you wanted to add another MenuItem later.
So, our app has all of the UI complete. Menu options, preferences, main layout, etc...
All that is left to do is to actually do something with the preferences.
SharedPreferences
These objects allow you to share preferences from one activity to another in the same app.
NOTE: It does not allow you to share preferences between applications
Declare a SharedPreferences object globally to the class.
SharedPreferences prefs;
How about we use them SharedPreferences. Inside the body of the onCreate() method,
prefs = PreferenceManager.getDefaultSharedPreferences(this);//get the preferences that are allowed to be given prefs.registerOnSharedPreferenceChangeListener(this);//set the listener to listen for changes in the preferences
Let the class implement OnSharedPreferenceListener to listen for when the preferences are changed. (I shouldn't have to show this)
An error should now pop up saying to add unimplemented methods.
Well, we were just getting there...
//called when the preferences are changed in any way
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,String key) {
txtMessage1.setText(prefs.getString("custom_message_1", ""));
txtMessage2.setText(prefs.getString("custom_message_2", ""));
}
setText(String text) - sets the text of the TextView to the passed String
prefs.getString(String key, String defv) - Gets a specific string from prefs.xml
Remember the keys from the prefs.xml that we set? Yup, I'm a boy of my word, this is where we use them.
The key tells the getString() method which item in the preferences to look for.
The defv is the default value, just in case the user has not set a custom message yet. In this case, we have just set a blank default value.
The full Main Activity with minimal comments:
package com.hotTACOcheese.preferencestutorial;
import android.app.Activity;
import android.os.Bundle;
import android.text.TextWatcher;
import android.util.Log;
import android.view.MenuItem;
import android.view.MenuInflater;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import android.view.Menu;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.preference.PreferenceManager;
public class MainActivity extends Activity implements OnSharedPreferenceChangeListener{
TextView txtMessage1;
TextView txtMessage2;
SharedPreferences prefs;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txtMessage1 = (TextView)this.findViewById(R.id.txtCustomMsg1);
txtMessage2 = (TextView)this.findViewById(R.id.txtCustomMsg2);
prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.registerOnSharedPreferenceChangeListener(this);
}
//called when user first clicks menu button
@Override
public boolean onCreateOptionsMenu(Menu menu){
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
//called when an option is clicked
@Override
public boolean onOptionsItemSelected(MenuItem item){
switch(item.getItemId()){
case R.id.item_prefs:
startActivity(new Intent(this, PrefsActivity.class));
break;
}
return true;
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,String key) {
txtMessage1.setText(prefs.getString("custom_message_1", ""));
txtMessage2.setText(prefs.getString("custom_message_2", ""));
}
}
Save, compile, and run. It should be good to go now.
Please give feedback.
Ask any questions that you may have!
PreferencesTutorial.zip (61.82K)
Number of downloads: 363





MultiQuote



|