Home | History | Annotate | Download | only in app_package
      1 package ${packageName};
      2 
      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;
     22 </#if>
     23 
     24 import java.util.List;
     25 
     26 /**
     27  * A {@link PreferenceActivity} that presents a set of application settings. On
     28  * handset devices, settings are presented as a single list. On tablets,
     29  * settings are split by category, with category headers shown to the left of
     30  * the list of settings.
     31  * <p>
     32  * See <a href="http://developer.android.com/design/patterns/settings.html">
     33  * Android Design: Settings</a> for design guidelines and the <a
     34  * href="http://developer.android.com/guide/topics/ui/settings.html">Settings
     35  * API Guide</a> for more information on developing a Settings UI.
     36  */
     37 public class ${activityClass} extends PreferenceActivity {
     38     /**
     39      * Determines whether to always show the simplified settings UI, where
     40      * settings are presented in a single list. When false, settings are shown
     41      * as a master/detail two-pane view on tablets. When true, a single pane is
     42      * shown on tablets.
     43      */
     44     private static final boolean ALWAYS_SIMPLE_PREFS = false;
     45 
     46     <#if parentActivityClass != "">
     47     @Override
     48     protected void onCreate(Bundle savedInstanceState) {
     49         super.onCreate(savedInstanceState);
     50         setupActionBar();
     51     }
     52 
     53     /**
     54      * Set up the {@link android.app.ActionBar}, if the API is available.
     55      */
     56     @TargetApi(Build.VERSION_CODES.HONEYCOMB)
     57     private void setupActionBar() {
     58         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
     59             // Show the Up button in the action bar.
     60             getActionBar().setDisplayHomeAsUpEnabled(true);
     61         }
     62     }
     63 
     64     @Override
     65     public boolean onOptionsItemSelected(MenuItem item) {
     66         switch (item.getItemId()) {
     67             case android.R.id.home:
     68                 // This ID represents the Home or Up button. In the case of this
     69                 // activity, the Up button is shown. Use NavUtils to allow users
     70                 // to navigate up one level in the application structure. For
     71                 // more details, see the Navigation pattern on Android Design:
     72                 //
     73                 // http://developer.android.com/design/patterns/navigation.html#up-vs-back
     74                 //
     75                 // TODO: If Settings has multiple levels, Up should navigate up
     76                 // that hierarchy.
     77                 NavUtils.navigateUpFromSameTask(this);
     78                 return true;
     79         }
     80         return super.onOptionsItemSelected(item);
     81     }
     82     </#if>
     83 
     84     @Override
     85     protected void onPostCreate(Bundle savedInstanceState) {
     86         super.onPostCreate(savedInstanceState);
     87 
     88         setupSimplePreferencesScreen();
     89     }
     90 
     91     /**
     92      * Shows the simplified settings UI if the device configuration if the
     93      * device configuration dictates that a simplified, single-pane UI should be
     94      * shown.
     95      */
     96     private void setupSimplePreferencesScreen() {
     97         if (!isSimplePreferences(this)) {
     98             return;
     99         }
    100 
    101         // In the simplified UI, fragments are not used at all and we instead
    102         // use the older PreferenceActivity APIs.
    103 
    104         // Add 'general' preferences.
    105         addPreferencesFromResource(R.xml.pref_general);
    106 
    107         // Add 'notifications' preferences, and a corresponding header.
    108         PreferenceCategory fakeHeader = new PreferenceCategory(this);
    109         fakeHeader.setTitle(R.string.pref_header_notifications);
    110         getPreferenceScreen().addPreference(fakeHeader);
    111         addPreferencesFromResource(R.xml.pref_notification);
    112 
    113         // Add 'data and sync' preferences, and a corresponding header.
    114         fakeHeader = new PreferenceCategory(this);
    115         fakeHeader.setTitle(R.string.pref_header_data_sync);
    116         getPreferenceScreen().addPreference(fakeHeader);
    117         addPreferencesFromResource(R.xml.pref_data_sync);
    118 
    119         // Bind the summaries of EditText/List/Dialog/Ringtone preferences to
    120         // their values. When their values change, their summaries are updated
    121         // to reflect the new value, per the Android Design guidelines.
    122         bindPreferenceSummaryToValue(findPreference("example_text"));
    123         bindPreferenceSummaryToValue(findPreference("example_list"));
    124         bindPreferenceSummaryToValue(findPreference("notifications_new_message_ringtone"));
    125         bindPreferenceSummaryToValue(findPreference("sync_frequency"));
    126     }
    127 
    128     /** {@inheritDoc} */
    129     @Override
    130     public boolean onIsMultiPane() {
    131         return isXLargeTablet(this) && !isSimplePreferences(this);
    132     }
    133 
    134     /**
    135      * Helper method to determine if the device has an extra-large screen. For
    136      * example, 10" tablets are extra-large.
    137      */
    138     private static boolean isXLargeTablet(Context context) {
    139         return (context.getResources().getConfiguration().screenLayout
    140         & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_XLARGE;
    141     }
    142 
    143     /**
    144      * Determines whether the simplified settings UI should be shown. This is
    145      * true if this is forced via {@link #ALWAYS_SIMPLE_PREFS}, or the device
    146      * doesn't have newer APIs like {@link PreferenceFragment}, or the device
    147      * doesn't have an extra-large screen. In these cases, a single-pane
    148      * "simplified" settings UI should be shown.
    149      */
    150     private static boolean isSimplePreferences(Context context) {
    151         return ALWAYS_SIMPLE_PREFS
    152                 || Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB
    153                 || !isXLargeTablet(context);
    154     }
    155 
    156     /** {@inheritDoc} */
    157     @Override
    158     @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    159     public void onBuildHeaders(List<Header> target) {
    160         if (!isSimplePreferences(this)) {
    161             loadHeadersFromResource(R.xml.pref_headers, target);
    162         }
    163     }
    164 
    165     /**
    166      * A preference value change listener that updates the preference's summary
    167      * to reflect its new value.
    168      */
    169     private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() {
    170         @Override
    171         public boolean onPreferenceChange(Preference preference, Object value) {
    172             String stringValue = value.toString();
    173 
    174             if (preference instanceof ListPreference) {
    175                 // For list preferences, look up the correct display value in
    176                 // the preference's 'entries' list.
    177                 ListPreference listPreference = (ListPreference) preference;
    178                 int index = listPreference.findIndexOfValue(stringValue);
    179 
    180                 // Set the summary to reflect the new value.
    181                 preference.setSummary(
    182                         index >= 0
    183                                 ? listPreference.getEntries()[index]
    184                                 : null);
    185 
    186             } else if (preference instanceof RingtonePreference) {
    187                 // For ringtone preferences, look up the correct display value
    188                 // using RingtoneManager.
    189                 if (TextUtils.isEmpty(stringValue)) {
    190                     // Empty values correspond to 'silent' (no ringtone).
    191                     preference.setSummary(R.string.pref_ringtone_silent);
    192 
    193                 } else {
    194                     Ringtone ringtone = RingtoneManager.getRingtone(
    195                             preference.getContext(), Uri.parse(stringValue));
    196 
    197                     if (ringtone == null) {
    198                         // Clear the summary if there was a lookup error.
    199                         preference.setSummary(null);
    200                     } else {
    201                         // Set the summary to reflect the new ringtone display
    202                         // name.
    203                         String name = ringtone.getTitle(preference.getContext());
    204                         preference.setSummary(name);
    205                     }
    206                 }
    207 
    208             } else {
    209                 // For all other preferences, set the summary to the value's
    210                 // simple string representation.
    211                 preference.setSummary(stringValue);
    212             }
    213             return true;
    214         }
    215     };
    216 
    217     /**
    218      * Binds a preference's summary to its value. More specifically, when the
    219      * preference's value is changed, its summary (line of text below the
    220      * preference title) is updated to reflect the value. The summary is also
    221      * immediately updated upon calling this method. The exact display format is
    222      * dependent on the type of preference.
    223      *
    224      * @see #sBindPreferenceSummaryToValueListener
    225      */
    226     private static void bindPreferenceSummaryToValue(Preference preference) {
    227         // Set the listener to watch for value changes.
    228         preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener);
    229 
    230         // Trigger the listener immediately with the preference's
    231         // current value.
    232         sBindPreferenceSummaryToValueListener.onPreferenceChange(preference,
    233                 PreferenceManager
    234                         .getDefaultSharedPreferences(preference.getContext())
    235                         .getString(preference.getKey(), ""));
    236     }
    237 
    238     /**
    239      * This fragment shows general preferences only. It is used when the
    240      * activity is showing a two-pane settings UI.
    241      */
    242     @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    243     public static class GeneralPreferenceFragment extends PreferenceFragment {
    244         @Override
    245         public void onCreate(Bundle savedInstanceState) {
    246             super.onCreate(savedInstanceState);
    247             addPreferencesFromResource(R.xml.pref_general);
    248 
    249             // Bind the summaries of EditText/List/Dialog/Ringtone preferences
    250             // to their values. When their values change, their summaries are
    251             // updated to reflect the new value, per the Android Design
    252             // guidelines.
    253             bindPreferenceSummaryToValue(findPreference("example_text"));
    254             bindPreferenceSummaryToValue(findPreference("example_list"));
    255         }
    256     }
    257 
    258     /**
    259      * This fragment shows notification preferences only. It is used when the
    260      * activity is showing a two-pane settings UI.
    261      */
    262     @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    263     public static class NotificationPreferenceFragment extends PreferenceFragment {
    264         @Override
    265         public void onCreate(Bundle savedInstanceState) {
    266             super.onCreate(savedInstanceState);
    267             addPreferencesFromResource(R.xml.pref_notification);
    268 
    269             // Bind the summaries of EditText/List/Dialog/Ringtone preferences
    270             // to their values. When their values change, their summaries are
    271             // updated to reflect the new value, per the Android Design
    272             // guidelines.
    273             bindPreferenceSummaryToValue(findPreference("notifications_new_message_ringtone"));
    274         }
    275     }
    276 
    277     /**
    278      * This fragment shows data and sync preferences only. It is used when the
    279      * activity is showing a two-pane settings UI.
    280      */
    281     @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    282     public static class DataSyncPreferenceFragment extends PreferenceFragment {
    283         @Override
    284         public void onCreate(Bundle savedInstanceState) {
    285             super.onCreate(savedInstanceState);
    286             addPreferencesFromResource(R.xml.pref_data_sync);
    287 
    288             // Bind the summaries of EditText/List/Dialog/Ringtone preferences
    289             // to their values. When their values change, their summaries are
    290             // updated to reflect the new value, per the Android Design
    291             // guidelines.
    292             bindPreferenceSummaryToValue(findPreference("sync_frequency"));
    293         }
    294     }
    295 }
    296