Home | History | Annotate | Download | only in spinner
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.example.spinner;
     18 
     19 import com.android.example.spinner.R;
     20 
     21 import android.app.Activity;
     22 import android.content.Context;
     23 import android.content.SharedPreferences;
     24 import android.os.Bundle;
     25 import android.view.View;
     26 import android.widget.AdapterView;
     27 import android.widget.ArrayAdapter;
     28 import android.widget.Spinner;
     29 import android.widget.TextView;
     30 import android.widget.Toast;
     31 import android.widget.AdapterView.OnItemSelectedListener;
     32 
     33 /**
     34  * Displays an Android spinner widget backed by data in an array. The
     35  * array is loaded from the strings.xml resources file.
     36  */
     37 public class SpinnerActivity extends Activity {
     38 
     39     /**
     40      * Fields to contain the current position and display contents of the spinner
     41      */
     42     protected int mPos;
     43     protected String mSelection;
     44 
     45     /**
     46      * ArrayAdapter connects the spinner widget to array-based data.
     47      */
     48     protected ArrayAdapter<CharSequence> mAdapter;
     49 
     50     /**
     51      *  The initial position of the spinner when it is first installed.
     52      */
     53     public static final int DEFAULT_POSITION = 2;
     54 
     55     /**
     56      * The name of a properties file that stores the position and
     57      * selection when the activity is not loaded.
     58      */
     59     public static final String PREFERENCES_FILE = "SpinnerPrefs";
     60 
     61     /**
     62      * These values are used to read and write the properties file.
     63      * PROPERTY_DELIMITER delimits the key and value in a Java properties file.
     64      * The "marker" strings are used to write the properties into the file
     65      */
     66     public static final String PROPERTY_DELIMITER = "=";
     67 
     68     /**
     69      * The key or label for "position" in the preferences file
     70      */
     71     public static final String POSITION_KEY = "Position";
     72 
     73     /**
     74      * The key or label for "selection" in the preferences file
     75      */
     76     public static final String SELECTION_KEY = "Selection";
     77 
     78     public static final String POSITION_MARKER =
     79             POSITION_KEY + PROPERTY_DELIMITER;
     80 
     81     public static final String SELECTION_MARKER =
     82             SELECTION_KEY + PROPERTY_DELIMITER;
     83 
     84     /**
     85      * Initializes the application and the activity.
     86      * 1) Sets the view
     87      * 2) Reads the spinner's backing data from the string resources file
     88      * 3) Instantiates a callback listener for handling selection from the
     89      *    spinner
     90      * Notice that this method includes code that can be uncommented to force
     91      * tests to fail.
     92      *
     93      * This method overrides the default onCreate() method for an Activity.
     94      *
     95      * @see android.app.Activity#onCreate(android.os.Bundle)
     96      */
     97     @Override
     98     public void onCreate(Bundle savedInstanceState) {
     99 
    100         /**
    101          * derived classes that use onCreate() overrides must always call the super constructor
    102          */
    103         super.onCreate(savedInstanceState);
    104 
    105         setContentView(R.layout.main);
    106 
    107         Spinner spinner = (Spinner) findViewById(R.id.Spinner01);
    108 
    109         /*
    110          * Create a backing mLocalAdapter for the Spinner from a list of the
    111          * planets. The list is defined by XML in the strings.xml file.
    112          */
    113 
    114         this.mAdapter = ArrayAdapter.createFromResource(this, R.array.Planets,
    115                 android.R.layout.simple_spinner_dropdown_item);
    116 
    117         /*
    118          * Attach the mLocalAdapter to the spinner.
    119          */
    120 
    121         spinner.setAdapter(this.mAdapter);
    122 
    123         /*
    124          * Create a listener that is triggered when Android detects the
    125          * user has selected an item in the Spinner.
    126          */
    127 
    128         OnItemSelectedListener spinnerListener = new myOnItemSelectedListener(this,this.mAdapter);
    129 
    130         /*
    131          * Attach the listener to the Spinner.
    132          */
    133 
    134         spinner.setOnItemSelectedListener(spinnerListener);
    135 
    136 
    137         /*
    138          * To demonstrate a failure in the preConditions test,
    139          * uncomment the following line.
    140          * The test will fail because the selection listener for the
    141          * Spinner is not set.
    142          */
    143          // spinner.setOnItemSelectedListener(null);
    144 
    145     }
    146 
    147 
    148     /**
    149      *  A callback listener that implements the
    150      *  {@link android.widget.AdapterView.OnItemSelectedListener} interface
    151      *  For views based on adapters, this interface defines the methods available
    152      *  when the user selects an item from the View.
    153      *
    154      */
    155     public class myOnItemSelectedListener implements OnItemSelectedListener {
    156 
    157         /*
    158          * provide local instances of the mLocalAdapter and the mLocalContext
    159          */
    160 
    161         ArrayAdapter<CharSequence> mLocalAdapter;
    162         Activity mLocalContext;
    163 
    164         /**
    165          *  Constructor
    166          *  @param c - The activity that displays the Spinner.
    167          *  @param ad - The Adapter view that
    168          *    controls the Spinner.
    169          *  Instantiate a new listener object.
    170          */
    171         public myOnItemSelectedListener(Activity c, ArrayAdapter<CharSequence> ad) {
    172 
    173           this.mLocalContext = c;
    174           this.mLocalAdapter = ad;
    175 
    176         }
    177 
    178         /**
    179          * When the user selects an item in the spinner, this method is invoked by the callback
    180          * chain. Android calls the item selected listener for the spinner, which invokes the
    181          * onItemSelected method.
    182          *
    183          * @see android.widget.AdapterView.OnItemSelectedListener#onItemSelected(
    184          *  android.widget.AdapterView, android.view.View, int, long)
    185          * @param parent - the AdapterView for this listener
    186          * @param v - the View for this listener
    187          * @param pos - the 0-based position of the selection in the mLocalAdapter
    188          * @param row - the 0-based row number of the selection in the View
    189          */
    190         public void onItemSelected(AdapterView<?> parent, View v, int pos, long row) {
    191 
    192             SpinnerActivity.this.mPos = pos;
    193             SpinnerActivity.this.mSelection = parent.getItemAtPosition(pos).toString();
    194             /*
    195              * Set the value of the text field in the UI
    196              */
    197             TextView resultText = (TextView)findViewById(R.id.SpinnerResult);
    198             resultText.setText(SpinnerActivity.this.mSelection);
    199         }
    200 
    201         /**
    202          * The definition of OnItemSelectedListener requires an override
    203          * of onNothingSelected(), even though this implementation does not use it.
    204          * @param parent - The View for this Listener
    205          */
    206         public void onNothingSelected(AdapterView<?> parent) {
    207 
    208             // do nothing
    209 
    210         }
    211     }
    212 
    213     /**
    214      * Restores the current state of the spinner (which item is selected, and the value
    215      * of that item).
    216      * Since onResume() is always called when an Activity is starting, even if it is re-displaying
    217      * after being hidden, it is the best place to restore state.
    218      *
    219      * Attempts to read the state from a preferences file. If this read fails,
    220      * assume it was just installed, so do an initialization. Regardless, change the
    221      * state of the spinner to be the previous position.
    222      *
    223      * @see android.app.Activity#onResume()
    224      */
    225     @Override
    226     public void onResume() {
    227 
    228         /*
    229          * an override to onResume() must call the super constructor first.
    230          */
    231 
    232         super.onResume();
    233 
    234         /*
    235          * Try to read the preferences file. If not found, set the state to the desired initial
    236          * values.
    237          */
    238 
    239         if (!readInstanceState(this)) setInitialState();
    240 
    241         /*
    242          * Set the spinner to the current state.
    243          */
    244 
    245         Spinner restoreSpinner = (Spinner)findViewById(R.id.Spinner01);
    246         restoreSpinner.setSelection(getSpinnerPosition());
    247 
    248     }
    249 
    250     /**
    251      * Store the current state of the spinner (which item is selected, and the value of that item).
    252      * Since onPause() is always called when an Activity is about to be hidden, even if it is about
    253      * to be destroyed, it is the best place to save state.
    254      *
    255      * Attempt to write the state to the preferences file. If this fails, notify the user.
    256      *
    257      * @see android.app.Activity#onPause()
    258      */
    259     @Override
    260     public void onPause() {
    261 
    262         /*
    263          * an override to onPause() must call the super constructor first.
    264          */
    265 
    266         super.onPause();
    267 
    268         /*
    269          * Save the state to the preferences file. If it fails, display a Toast, noting the failure.
    270          */
    271 
    272         if (!writeInstanceState(this)) {
    273              Toast.makeText(this,
    274                      "Failed to write state!", Toast.LENGTH_LONG).show();
    275           }
    276     }
    277 
    278     /**
    279      * Sets the initial state of the spinner when the application is first run.
    280      */
    281     public void setInitialState() {
    282 
    283         this.mPos = DEFAULT_POSITION;
    284 
    285     }
    286 
    287     /**
    288      * Read the previous state of the spinner from the preferences file
    289      * @param c - The Activity's Context
    290      */
    291     public boolean readInstanceState(Context c) {
    292 
    293         /*
    294          * The preferences are stored in a SharedPreferences file. The abstract implementation of
    295          * SharedPreferences is a "file" containing a hashmap. All instances of an application
    296          * share the same instance of this file, which means that all instances of an application
    297          * share the same preference settings.
    298          */
    299 
    300         /*
    301          * Get the SharedPreferences object for this application
    302          */
    303 
    304         SharedPreferences p = c.getSharedPreferences(PREFERENCES_FILE, MODE_WORLD_READABLE);
    305         /*
    306          * Get the position and value of the spinner from the file, or a default value if the
    307          * key-value pair does not exist.
    308          */
    309         this.mPos = p.getInt(POSITION_KEY, SpinnerActivity.DEFAULT_POSITION);
    310         this.mSelection = p.getString(SELECTION_KEY, "");
    311 
    312         /*
    313          * SharedPreferences doesn't fail if the code tries to get a non-existent key. The
    314          * most straightforward way to indicate success is to return the results of a test that
    315          * SharedPreferences contained the position key.
    316          */
    317 
    318           return (p.contains(POSITION_KEY));
    319 
    320         }
    321 
    322     /**
    323      * Write the application's current state to a properties repository.
    324      * @param c - The Activity's Context
    325      *
    326      */
    327     public boolean writeInstanceState(Context c) {
    328 
    329         /*
    330          * Get the SharedPreferences object for this application
    331          */
    332 
    333         SharedPreferences p =
    334                 c.getSharedPreferences(SpinnerActivity.PREFERENCES_FILE, MODE_WORLD_READABLE);
    335 
    336         /*
    337          * Get the editor for this object. The editor interface abstracts the implementation of
    338          * updating the SharedPreferences object.
    339          */
    340 
    341         SharedPreferences.Editor e = p.edit();
    342 
    343         /*
    344          * Write the keys and values to the Editor
    345          */
    346 
    347         e.putInt(POSITION_KEY, this.mPos);
    348         e.putString(SELECTION_KEY, this.mSelection);
    349 
    350         /*
    351          * Commit the changes. Return the result of the commit. The commit fails if Android
    352          * failed to commit the changes to persistent storage.
    353          */
    354 
    355         return (e.commit());
    356 
    357     }
    358 
    359     public int getSpinnerPosition() {
    360         return this.mPos;
    361     }
    362 
    363     public void setSpinnerPosition(int pos) {
    364         this.mPos = pos;
    365     }
    366 
    367     public String getSpinnerSelection() {
    368         return this.mSelection;
    369     }
    370 
    371     public void setSpinnerSelection(String selection) {
    372         this.mSelection = selection;
    373     }
    374 }
    375