1. To begin, add some values to
res/values/strings.xml
.<?xml version="1.0" encoding="utf-8"?>
<!-- Phil Brown -->
<resources>
<resources>
<string name="app_name">MyGreatApp</string>
<string name="user_settings">user_settings</string>
<string name="app_settings">MyGreatApp Settings</string>
<string name="prefs_account">Account Settings</string>
<string name="prefs_app">Application Settings</string>
<string name="prefs_other">Other</string>
<string name="option_1_key">option_1_key</string>
<string name="option_1_title">Option 1</string>
<string name="option_1_summary">This summary describes what this bar is for.</string>
<string name="option_2_key">option_2_key</string>
<string name="option_2_title">Option 2</string>
<string name="option_2_summary">This summary describes what option 2 does.</string>
<string name="app_info_key">app_info</string>
<string name="app_info_title">Application Info</string>
<string name="app_info_summary">copyright, version, etc</string>
<string name="app_copyright_key">app_copyright</string>
<string name="app_copyright_title">© 2011</string>
<string name="app_copyright_summary">My Company</string>
<string name="app_version_key">app_version</string>
<string name="app_version_title">version</string>
</resources>
Modify the Strings "app_name", "app_settings", "option_1_key", "option_1_title", "option_1_summary", "option_2_key", "option_2_title", "option_2_summary", "app_copyright_summary", and "app_copyright_summary" to better reflect your company and your preferences.
2. Next, create your main preferences XML (
res/layout/preferences.xml
):<?xml version="1.0" encoding="utf-8"?>
<!-- Phil Brown -->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="@string/prefs_app" >
<PreferenceScreen
android:key="@string/option_1_key"
android:title="@string/
option_1_title"
android:summary="@string/
option_1_summary" />
<PreferenceScreen
android:key="@string/
option_2_key"
android:title="@string/
option_2_title"
android:summary="@string/
option_2_summary" />
</PreferenceCategory>
<PreferenceCategory
android:title="@string/prefs_other">
<PreferenceScreen
android:key="@string/app_info_key"
android:title="@string/app_info_title"
android:summary="@string/app_info_summary">
<Preference
android:key="@string/app_copyright_key"
android:title="@string/app_copyright_title"
android:summary="@string/app_copyright_summary" />
<Preference
android:key="@string/app_version_key"
android:title="@string/app_version_title" />
</PreferenceScreen>
<PreferenceScreen android:title="Contact us" >
<intent android:action="android.intent.action.SENDTO"
android:data="mailto:myemailaddress@someplace.com" />
</PreferenceScreen>
<PreferenceScreen android:title="Check for updates" >
<intent android:action="android.intent.action.VIEW"
android:data="market://details?id=com.example.android" />
</PreferenceScreen>
</PreferenceCategory>
</PreferenceScreen>
Replacing the contact and update intents with correct mailto and market links.
3. Create the file
res/layout/seekbar_preference.xml
with the following contents:<?xml version="1.0" encoding="utf-8"?>
<!-- Phil Brown --><LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/seekbar_title"
android:text="test"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dip"
android:paddingRight="10dip"
android:paddingTop="10dip"
android:textSize="20dip" />
<TextView
android:id="@+id/seekbar_summary"
android:text="test"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingLeft="10dip"
android:paddingRight="10dip"
android:textColor="#0C68D9" />
<SeekBar
android:id="@+id/seekbar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:padding="20dip"
android:max="100" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="30dip" >
<TextView
android:id="@+id/min_value"
android:layout_width="50dip"
android:layout_height="20dip"
android:layout_gravity="left"
android:paddingLeft="20dip" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<Button
android:id="@+id/save_slider"
android:layout_width="120dip"
android:layout_height="50dip"
android:paddingLeft="10dip"
android:text="Save" >
</Button>
<View
android:layout_width="10dip"
android:layout_height="50dip" >
</View>
<Button
android:id="@+id/cancel_slider"
android:layout_width="120dip"
android:layout_height="50dip"
android:paddingRight="10dip"
android:text="Cancel" >
</Button>
</LinearLayout>
</LinearLayout>
4. Create a new class called
Constants
with the following contents:
/** Contains contants.
* @author Phil Brown
*/
public class Constants {
/** String used for packing and unpacking Intent extras for the
* SeekBarPreference activity */
public static final String PREFERENCE_BAR_TITLE = "title",
PREFERENCE_BAR_SUMMARY = "summary",
PREFERENCE_BAR_MID = "default_value",
PREFERENCE_BAR_KEY = "key";
}//Constants
5. Create a new Activity called
SeekBarPreference.java
with the following contents:import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.content.SharedPreferences;
/**
* Activity for changing settings using a SeekBar.
* @author Phil Brown
*/
public class SeekBarPreference extends Activity {
/** The key of the SharedPreferences value*/
private String key;
/** The title of the settings option */
private String title;
/** The summary of the settings option */
private String summary;
/** The seekbar */
private SeekBar seekbar;
/** The seekbar's average value */
private int bar_mid;
/** The save settings button */
private Button save_button;
/** The cancel changes button */
private Button cancel_button;
/** Contains user settings using key/value pairing. */
private SharedPreferences user_prefs;
/** Allows edit access to {@link #user_prefs}
private SharedPreferences.Editor user_preferences;
/** Initializes the layout*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.seekbar_preference);
this.seekbar = (SeekBar) findViewById(R.id.seekbar);
final TextView progress_value = (TextView) findViewById(R.id.min_value);
progress_value.setText(Integer.toString(this.seekbar.getProgress()));
this.seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
progress_value.setText(Integer.toString(progress)); }
@Override
public void onStartTrackingTouch(SeekBar seekBar) {}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {}
});
this.handleNewIntent(this.getIntent());
((TextView) findViewById(R.id.seekbar_title)).setText(this.title);
((TextView) findViewById(R.id.seekbar_summary)).setText(this.summary);
save_button = (Button) findViewById(R.id.save_slider);
cancel_button = (Button) findViewById(R.id.cancel_slider);
save_button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
save();
}
});
cancel_button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
this.user_prefs = getSharedPreferences(getString(R.string.user_settings),
Activity.MODE_PRIVATE);
@Override
public void onStartTrackingTouch(SeekBar seekBar) {}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {}
});
this.handleNewIntent(this.getIntent());
((TextView) findViewById(R.id.seekbar_title)).setText(this.title);
((TextView) findViewById(R.id.seekbar_summary)).setText(this.summary);
save_button = (Button) findViewById(R.id.save_slider);
cancel_button = (Button) findViewById(R.id.cancel_slider);
save_button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
save();
}
});
cancel_button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
this.user_prefs = getSharedPreferences(getString(R.string.user_settings),
Activity.MODE_PRIVATE);
this.user_preferences = this.user_prefs.edit();
}//onCreate
/** Unpacks the new Intent */
public void handleNewIntent(Intent intent) {
this.key = intent.getStringExtra(Constants.PREFERENCE_BAR_KEY);
this.title = intent.getStringExtra(Constants.PREFERENCE_BAR_TITLE);
this.summary = intent.getStringExtra(Constants.PREFERENCE_BAR_SUMMARY);
/** Unpacks the new Intent */
public void handleNewIntent(Intent intent) {
this.key = intent.getStringExtra(Constants.PREFERENCE_BAR_KEY);
this.title = intent.getStringExtra(Constants.PREFERENCE_BAR_TITLE);
this.summary = intent.getStringExtra(Constants.PREFERENCE_BAR_SUMMARY);
this.bar_mid = intent.getIntArrayExtra(Constants.PREFERENCE_BAR_MID);
this.seekbar.setMax(this.bar_mid * 2);
this.seekbar.setProgress(G.user_prefs.getInt(this.key, this.bar_mid));
}//handleNewIntent
/** Saves the user settings to the SharedPreferences. If the user sets
* the progress to zero, use 1 instead. */
public void save(){
this.user_preferences.putInt(this.key, this.seekbar.getProgress());
this.user_preferences.commit();
finish();
}//save
}//SeekBarPreference
6. Now add the following lines to the Android Manifest inside the application attribute:
<activity android:name=".SeekBarPreference"
android:label="@string/app_settings"
android:launchMode="singleTop"
android:theme="@android:style/Theme.Dialog" >
</activity>
7. Lastly, create the class Preferences.java. This is your main Preference class:
package org.cyclopath.android;
import org.cyclopath.android.conf.Constants;
import android.content.Intent;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceActivity;
/**
* User Preferences Activity
* @author Phil Brown
*/
public class Preferences extends PreferenceActivity {
/** Intent for modifying option 1 */
private Intent option_1_settings;
/** Intent for modifying option2 */
private Intent option_2_settings;
@Override
/** Initialize the layout */
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.layout.preferences);
Preference version = (Preference)
findPreference(getString(R.string.app_version_key));
String version_name;
try {
version_name = getPackageManager()
.getPackageInfo(getPackageName(), 0)
.versionName;
} catch (NameNotFoundException e) {
version_name = "unknown";
}
version.setSummary(version_name);
}//onCreate
/** Initialize the Intents and set the preference Intents to open a new */
@Override
public void onStart() {
super.onStart();
this.initializeIntents();
((Preference) findPreference(getString(R.string.option_1_key)))
.setIntent(option_1_settings);
((Preference) findPreference(getString(R.string.option_2_key)))
.setIntent(option_2_settings);
}//onStart
/** Initialize the Intents in order to correctly launch a new SeekBarPreference */
public void initializeIntents() {
gps_main_settings = new Intent(this, SeekBarPreference.class);
gps_main_settings.putExtra(Constants.PREFERENCE_BAR_TITLE,
getString(R.string.option_1_title));
gps_main_settings.putExtra(Constants.PREFERENCE_BAR_SUMMARY,
getString(R.string.option_1_summary));
gps_main_settings.putExtra(Constants.PREFERENCE_BAR_KEY,
getString(R.string.option_1_key));
gps_main_settings.putExtra(Constants.PREFERENCE_BAR_MID, 50);
gps_service_settings = new Intent(this, SeekBarPreference.class);
gps_service_settings.putExtra(Constants.PREFERENCE_BAR_TITLE,
getString(R.string.option_2_title));
gps_service_settings.putExtra(Constants.PREFERENCE_BAR_SUMMARY,
getString(R.string.option_2_summary));
gps_service_settings.putExtra(Constants.PREFERENCE_BAR_KEY,
getString(R.string.option_2_key));
gps_service_settings.putExtra(Constants.PREFERENCE_BAR_MID, 50);
}//initializeIntents
}//Preferences