Abstract
In this post I'll show you how to develop an Android app to be able to accept user configurations throw the API Preferences. Using this API you can easy show, store and retreive user configurations, without care about how those informations are stored. As you will see, this is actually easy to do, just write an XML file and some bunch of Java code.
Before start
In order to show how Preferences works, I'll write a simple Android app that only shows the user configuration and open the configuration menù. This menù is made using only the layout files, without hard coding. In this example I'll use the SDK 11 (Honeycomb), beacause the older versions are not compatible.
What we need
For use Preferences, you don't need nothing but the Android SDK, because this API is integrated in it. So, if you don't have the IDE, download it from here.
Preferences.xml
The preferences options are stored in a XML file, just like a normal Activity layout file. Every option is identified by an android:key attribute, a string key that allow you to retrive the option value.
The root element is PreferenceScreen that define the menù option layout.
The option elements are:
- CheckBoxPreference: a checkbox that rappresent a boolean value
- EditTextPreference: shows a EditText of free-text string
- ListPreference: shows a list of selectable items
- MultiSelectListPreference: like the above, but allows user to select several items
- RingtonePreference: shows a list of the ringtones from on the device
- SwitchPreference: similar to CheckBoxPreference but shows a toggleable switch
Ready, steady, code!
Finally we are ready to code our preferences menù. First of all, lets define what options we want to show. For example I'll create a simple menù with a checkbox and an edittext in 2 different categories.
Well, check if res/xml directory exists (if not make it) and add a preferences.xml file. So, write the following code:
Then create a class that rappresent the menù. The class extends android.preference.PreferenceFragment, and it displays the menù itself. In the method onCreate we call addPreferencesFromResource to load graphical interface from the file preferences.xml, like so:
In order to store and display the user option, I'll create 2 activities: one, MainActivity, shows the user options and the other, SetPreferencesActivity, displays the menù and store the values.
The MainActivity layout file (res/layout/main.xml) has 2 TextView and a button for lunch the SetPreferencesActivity as follows:
The SetPreferencesActivity layout file (res/layout/setpreferences.xml) shows the fragment created above and a button for come back to MainActivity, just like that:
Now create the 2 Java classes for the activities. The SetPreferencesActivity class create the content from the file setpreferences.xml and close itself on button back click, in this way:
The MainActivity class provides to load the graphics from main.xml file, then load the user preferences at the boot. On the edit button click shows the SetPreferencesActivity and, then this one ends, reload the properties, as follows:
Don't forget to add SetPreferencesActivity in your AndroidManifest.xml in order to correct display then, in this manner:
Well, check if res/xml directory exists (if not make it) and add a preferences.xml file. So, write the following code:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="First PreferenceCategory">
<CheckBoxPreference
android:key="checkbox_preference"
android:title="title checkbox preference"
android:summary="summary of the checkbox preference" />
</PreferenceCategory>
<PreferenceCategory
android:title="Second PreferenceCategory">
<EditTextPreference
android:key="edittext_preference"
android:title="title edittext preference"
android:summary="summary of the edittext preference"
android:dialogTitle="dialog title edittext preference" />
</PreferenceCategory>
</PreferenceScreen>
Then create a class that rappresent the menù. The class extends android.preference.PreferenceFragment, and it displays the menù itself. In the method onCreate we call addPreferencesFromResource to load graphical interface from the file preferences.xml, like so:
package com.blogspot.virtualinsanity106.preferences.fragments;
import com.blogspot.virtualinsanity106.preferences.R; //NOT android.R
import android.os.Bundle;
import android.preference.PreferenceFragment;
import android.util.Log;
public class PreferencesTest extends PreferenceFragment {
private static final String TAG = "PreferencesTest";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//create the fragment content from preferences.xml
addPreferencesFromResource(R.xml.preferences);
Log.d(TAG, "Content created");
}
}
In order to store and display the user option, I'll create 2 activities: one, MainActivity, shows the user options and the other, SetPreferencesActivity, displays the menù and store the values.
The MainActivity layout file (res/layout/main.xml) has 2 TextView and a button for lunch the SetPreferencesActivity as follows:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- this shows the edittext_preference preference -->
<TextView
android:id="@+id/textview_edittext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=""
android:textAppearance="?android:attr/textAppearanceLarge" />
<!-- this shows the checkbox_preference preference -->
<TextView
android:id="@+id/textview_checkbox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="" />
<!-- this shows the SetPreferencesActivity activity-->
<Button
android:id="@+id/button_edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_edit_label"
android:onClick="onEditClick"/><!-- function to show the edit activity -->
</LinearLayout>
The SetPreferencesActivity layout file (res/layout/setpreferences.xml) shows the fragment created above and a button for come back to MainActivity, just like that:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- this is the preferences fragment -->
<fragment
android:id="@+id/fragment_preferences"
android:name="com.blogspot.virtualinsanity106.preferences.fragments.PreferencesTest"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<!-- this is the "Back" button -->
<Button
android:id="@+id/button_back"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/button_back_label"
android:onClick="onBackClick"/><!-- function to come back to the main activity -->
</LinearLayout>
Now create the 2 Java classes for the activities. The SetPreferencesActivity class create the content from the file setpreferences.xml and close itself on button back click, in this way:
package com.blogspot.virtualinsanity106.preferences;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
public class SetPreferencesActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.setpreferences);
}
public void onBackClick(View v){
setResult(RESULT_OK);
finish();
}
}
The MainActivity class provides to load the graphics from main.xml file, then load the user preferences at the boot. On the edit button click shows the SetPreferencesActivity and, then this one ends, reload the properties, as follows:
package com.blogspot.virtualinsanity106.preferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
private TextView txtDisplayEditText;
private TextView txtDisplayCheck;
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
loadPreferences(); //when the preferencesactivity ends, reload preferences when properties activity close
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);//set the content from main.xml
txtDisplayEditText = (TextView) findViewById(R.id.textview_edittext);
txtDisplayCheck = (TextView) findViewById(R.id.textview_checkbox);
loadPreferences();//load the edited preferences
}
public void onEditClick(View v){
//open the properties activity
Log.d(TAG, "Start edit");
Intent intent = new Intent();
intent.setClass(MainActivity.this, SetPreferencesActivity.class);
startActivityForResult(intent, 0);
}
private void loadPreferences(){
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); //load the preferences
txtDisplayEditText.setText(sharedPreferences.getString("edittext_preference", getString(R.string.edittext_default_text))); //by default show the edittext_default_text string
boolean isCheckboxSelected = sharedPreferences.getBoolean("checkbox_preference", false);//by default the checkbox isn't selected
if(isCheckboxSelected)//if the checkbox is selected, show the "checkbox_true" string, otherwise show the "checkbox_false" string
txtDisplayCheck.setText(getString(R.string.checkbox_true));
else
txtDisplayCheck.setText(getString(R.string.checkbox_false));
}
}
Don't forget to add SetPreferencesActivity in your AndroidManifest.xml in order to correct display then, in this manner:
<activity android:name="SetPreferencesActivity"></activity>
Conclusions
In this post I showed you how to display and store an options menù in an Android app, and how read the user options throw the Preferences API. This API is included in the Android SDK, so we don't need to add jars in our project. In this post I had added some "non-option element" (like the Back button) in the menù without using a work-around for emulate the functions but just add that in the menù layout.
Some files are not included in this post, you can download the entire project here