1 package ${packageName};
3 import android.annotation.TargetApi;
4 import android.content.Context;
5 import android.content.res.Configuration;
6 import android.media.Ringtone;
7 import android.media.RingtoneManager;
8 import android.net.Uri;
9 import android.os.Build;
10 import android.os.Bundle;
11 import android.preference.ListPreference;
12 import android.preference.Preference;
13 import android.preference.PreferenceActivity;
14 import android.preference.PreferenceCategory;
15 import android.preference.PreferenceFragment;
16 import android.preference.PreferenceManager;
17 import android.preference.RingtonePreference;
18 import android.text.TextUtils;
19 <#if parentActivityClass != "">
20 import android.view.MenuItem;
21 import android.support.v4.app.NavUtils;
23 <#if applicationPackage??>import ${applicationPackage}.R;</#if>
25 import java.util.List;
28 * A {@link PreferenceActivity} that presents a set of application settings. On
29 * handset devices, settings are presented as a single list. On tablets,
30 * settings are split by category, with category headers shown to the left of
31 * the list of settings.
33 * See <a href="http://developer.android.com/design/patterns/settings.html">
34 * Android Design: Settings</a> for design guidelines and the <a
35 * href="http://developer.android.com/guide/topics/ui/settings.html">Settings
36 * API Guide</a> for more information on developing a Settings UI.
38 public class ${activityClass} extends PreferenceActivity {
40 * Determines whether to always show the simplified settings UI, where
41 * settings are presented in a single list. When false, settings are shown
42 * as a master/detail two-pane view on tablets. When true, a single pane is
45 private static final boolean ALWAYS_SIMPLE_PREFS = false;
47 <#if parentActivityClass != "">
49 protected void onCreate(Bundle savedInstanceState) {
50 super.onCreate(savedInstanceState);
55 * Set up the {@link android.app.ActionBar}, if the API is available.
57 @TargetApi(Build.VERSION_CODES.HONEYCOMB)
58 private void setupActionBar() {
59 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
60 // Show the Up button in the action bar.
61 getActionBar().setDisplayHomeAsUpEnabled(true);
66 public boolean onOptionsItemSelected(MenuItem item) {
67 int id = item.getItemId();
68 if (id == android.R.id.home) {
69 // This ID represents the Home or Up button. In the case of this
70 // activity, the Up button is shown. Use NavUtils to allow users
71 // to navigate up one level in the application structure. For
72 // more details, see the Navigation pattern on Android Design:
74 // http://developer.android.com/design/patterns/navigation.html#up-vs-back
76 // TODO: If Settings has multiple levels, Up should navigate up
78 NavUtils.navigateUpFromSameTask(this);
81 return super.onOptionsItemSelected(item);
86 protected void onPostCreate(Bundle savedInstanceState) {
87 super.onPostCreate(savedInstanceState);
89 setupSimplePreferencesScreen();
93 * Shows the simplified settings UI if the device configuration if the
94 * device configuration dictates that a simplified, single-pane UI should be
97 private void setupSimplePreferencesScreen() {
98 if (!isSimplePreferences(this)) {
102 // In the simplified UI, fragments are not used at all and we instead
103 // use the older PreferenceActivity APIs.
105 // Add 'general' preferences.
106 addPreferencesFromResource(R.xml.pref_general);
108 // Add 'notifications' preferences, and a corresponding header.
109 PreferenceCategory fakeHeader = new PreferenceCategory(this);
110 fakeHeader.setTitle(R.string.pref_header_notifications);
111 getPreferenceScreen().addPreference(fakeHeader);
112 addPreferencesFromResource(R.xml.pref_notification);
114 // Add 'data and sync' preferences, and a corresponding header.
115 fakeHeader = new PreferenceCategory(this);
116 fakeHeader.setTitle(R.string.pref_header_data_sync);
117 getPreferenceScreen().addPreference(fakeHeader);
118 addPreferencesFromResource(R.xml.pref_data_sync);
120 // Bind the summaries of EditText/List/Dialog/Ringtone preferences to
121 // their values. When their values change, their summaries are updated
122 // to reflect the new value, per the Android Design guidelines.
123 bindPreferenceSummaryToValue(findPreference("example_text"));
124 bindPreferenceSummaryToValue(findPreference("example_list"));
125 bindPreferenceSummaryToValue(findPreference("notifications_new_message_ringtone"));
126 bindPreferenceSummaryToValue(findPreference("sync_frequency"));
131 public boolean onIsMultiPane() {
132 return isXLargeTablet(this) && !isSimplePreferences(this);
136 * Helper method to determine if the device has an extra-large screen. For
137 * example, 10" tablets are extra-large.
139 private static boolean isXLargeTablet(Context context) {
140 return (context.getResources().getConfiguration().screenLayout
141 & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_XLARGE;
145 * Determines whether the simplified settings UI should be shown. This is
146 * true if this is forced via {@link #ALWAYS_SIMPLE_PREFS}, or the device
147 * doesn't have newer APIs like {@link PreferenceFragment}, or the device
148 * doesn't have an extra-large screen. In these cases, a single-pane
149 * "simplified" settings UI should be shown.
151 private static boolean isSimplePreferences(Context context) {
152 return ALWAYS_SIMPLE_PREFS
153 || Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB
154 || !isXLargeTablet(context);
159 @TargetApi(Build.VERSION_CODES.HONEYCOMB)
160 public void onBuildHeaders(List<Header> target) {
161 if (!isSimplePreferences(this)) {
162 loadHeadersFromResource(R.xml.pref_headers, target);
167 * A preference value change listener that updates the preference's summary
168 * to reflect its new value.
170 private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() {
172 public boolean onPreferenceChange(Preference preference, Object value) {
173 String stringValue = value.toString();
175 if (preference instanceof ListPreference) {
176 // For list preferences, look up the correct display value in
177 // the preference's 'entries' list.
178 ListPreference listPreference = (ListPreference) preference;
179 int index = listPreference.findIndexOfValue(stringValue);
181 // Set the summary to reflect the new value.
182 preference.setSummary(
184 ? listPreference.getEntries()[index]
187 } else if (preference instanceof RingtonePreference) {
188 // For ringtone preferences, look up the correct display value
189 // using RingtoneManager.
190 if (TextUtils.isEmpty(stringValue)) {
191 // Empty values correspond to 'silent' (no ringtone).
192 preference.setSummary(R.string.pref_ringtone_silent);
195 Ringtone ringtone = RingtoneManager.getRingtone(
196 preference.getContext(), Uri.parse(stringValue));
198 if (ringtone == null) {
199 // Clear the summary if there was a lookup error.
200 preference.setSummary(null);
202 // Set the summary to reflect the new ringtone display
204 String name = ringtone.getTitle(preference.getContext());
205 preference.setSummary(name);
210 // For all other preferences, set the summary to the value's
211 // simple string representation.
212 preference.setSummary(stringValue);
219 * Binds a preference's summary to its value. More specifically, when the
220 * preference's value is changed, its summary (line of text below the
221 * preference title) is updated to reflect the value. The summary is also
222 * immediately updated upon calling this method. The exact display format is
223 * dependent on the type of preference.
225 * @see #sBindPreferenceSummaryToValueListener
227 private static void bindPreferenceSummaryToValue(Preference preference) {
228 // Set the listener to watch for value changes.
229 preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener);
231 // Trigger the listener immediately with the preference's
233 sBindPreferenceSummaryToValueListener.onPreferenceChange(preference,
235 .getDefaultSharedPreferences(preference.getContext())
236 .getString(preference.getKey(), ""));
240 * This fragment shows general preferences only. It is used when the
241 * activity is showing a two-pane settings UI.
243 @TargetApi(Build.VERSION_CODES.HONEYCOMB)
244 public static class GeneralPreferenceFragment extends PreferenceFragment {
246 public void onCreate(Bundle savedInstanceState) {
247 super.onCreate(savedInstanceState);
248 addPreferencesFromResource(R.xml.pref_general);
250 // Bind the summaries of EditText/List/Dialog/Ringtone preferences
251 // to their values. When their values change, their summaries are
252 // updated to reflect the new value, per the Android Design
254 bindPreferenceSummaryToValue(findPreference("example_text"));
255 bindPreferenceSummaryToValue(findPreference("example_list"));
260 * This fragment shows notification preferences only. It is used when the
261 * activity is showing a two-pane settings UI.
263 @TargetApi(Build.VERSION_CODES.HONEYCOMB)
264 public static class NotificationPreferenceFragment extends PreferenceFragment {
266 public void onCreate(Bundle savedInstanceState) {
267 super.onCreate(savedInstanceState);
268 addPreferencesFromResource(R.xml.pref_notification);
270 // Bind the summaries of EditText/List/Dialog/Ringtone preferences
271 // to their values. When their values change, their summaries are
272 // updated to reflect the new value, per the Android Design
274 bindPreferenceSummaryToValue(findPreference("notifications_new_message_ringtone"));
279 * This fragment shows data and sync preferences only. It is used when the
280 * activity is showing a two-pane settings UI.
282 @TargetApi(Build.VERSION_CODES.HONEYCOMB)
283 public static class DataSyncPreferenceFragment extends PreferenceFragment {
285 public void onCreate(Bundle savedInstanceState) {
286 super.onCreate(savedInstanceState);
287 addPreferencesFromResource(R.xml.pref_data_sync);
289 // Bind the summaries of EditText/List/Dialog/Ringtone preferences
290 // to their values. When their values change, their summaries are
291 // updated to reflect the new value, per the Android Design
293 bindPreferenceSummaryToValue(findPreference("sync_frequency"));