UI Android

//
//src\com\android\example\spinner\SpinnerActivity.java
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.example.spinner;
import com.android.example.spinner.R;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemSelectedListener;
/**
 * Displays an Android spinner widget backed by data in an array. The
 * array is loaded from the strings.xml resources file.
 */
public class SpinnerActivity extends Activity {
    /**
     * Fields to contain the current position and display contents of the spinner
     */
    protected int mPos;
    protected String mSelection;
    /**
     * ArrayAdapter connects the spinner widget to array-based data.
     */
    protected ArrayAdapter mAdapter;
    /**
     *  The initial position of the spinner when it is first installed.
     */
    public static final int DEFAULT_POSITION = 2;
    /**
     * The name of a properties file that stores the position and
     * selection when the activity is not loaded.
     */
    public static final String PREFERENCES_FILE = "SpinnerPrefs";
    /**
     * These values are used to read and write the properties file.
     * PROPERTY_DELIMITER delimits the key and value in a Java properties file.
     * The "marker" strings are used to write the properties into the file
     */
    public static final String PROPERTY_DELIMITER = "=";
    /**
     * The key or label for "position" in the preferences file
     */
    public static final String POSITION_KEY = "Position";
    /**
     * The key or label for "selection" in the preferences file
     */
    public static final String SELECTION_KEY = "Selection";
    public static final String POSITION_MARKER =
            POSITION_KEY + PROPERTY_DELIMITER;
    public static final String SELECTION_MARKER =
            SELECTION_KEY + PROPERTY_DELIMITER;
    /**
     * Initializes the application and the activity.
     * 1) Sets the view
     * 2) Reads the spinner's backing data from the string resources file
     * 3) Instantiates a callback listener for handling selection from the
     *    spinner
     * Notice that this method includes code that can be uncommented to force
     * tests to fail.
     *
     * This method overrides the default onCreate() method for an Activity.
     *
     * @see android.app.Activity#onCreate(android.os.Bundle)
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        /**
         * derived classes that use onCreate() overrides must always call the super constructor
         */
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Spinner spinner = (Spinner) findViewById(R.id.Spinner01);
        /*
         * Create a backing mLocalAdapter for the Spinner from a list of the
         * planets. The list is defined by XML in the strings.xml file.
         */
        this.mAdapter = ArrayAdapter.createFromResource(this, R.array.Planets,
                android.R.layout.simple_spinner_dropdown_item);
        /*
         * Attach the mLocalAdapter to the spinner.
         */
        spinner.setAdapter(this.mAdapter);
        /*
         * Create a listener that is triggered when Android detects the
         * user has selected an item in the Spinner.
         */
        OnItemSelectedListener spinnerListener = new myOnItemSelectedListener(this,this.mAdapter);
        /*
         * Attach the listener to the Spinner.
         */
        spinner.setOnItemSelectedListener(spinnerListener);
        /*
         * To demonstrate a failure in the preConditions test,
         * uncomment the following line.
         * The test will fail because the selection listener for the
         * Spinner is not set.
         */
         // spinner.setOnItemSelectedListener(null);
    }
    /**
     *  A callback listener that implements the
     *  {@link android.widget.AdapterView.OnItemSelectedListener} interface
     *  For views based on adapters, this interface defines the methods available
     *  when the user selects an item from the View.
     *
     */
    public class myOnItemSelectedListener implements OnItemSelectedListener {
        /*
         * provide local instances of the mLocalAdapter and the mLocalContext
         */
        ArrayAdapter mLocalAdapter;
        Activity mLocalContext;
        /**
         *  Constructor
         *  @param c - The activity that displays the Spinner.
         *  @param ad - The Adapter view that
         *    controls the Spinner.
         *  Instantiate a new listener object.
         */
        public myOnItemSelectedListener(Activity c, ArrayAdapter ad) {
          this.mLocalContext = c;
          this.mLocalAdapter = ad;
        }
        /**
         * When the user selects an item in the spinner, this method is invoked by the callback
         * chain. Android calls the item selected listener for the spinner, which invokes the
         * onItemSelected method.
         *
         * @see android.widget.AdapterView.OnItemSelectedListener#onItemSelected(
         *  android.widget.AdapterView, android.view.View, int, long)
         * @param parent - the AdapterView for this listener
         * @param v - the View for this listener
         * @param pos - the 0-based position of the selection in the mLocalAdapter
         * @param row - the 0-based row number of the selection in the View
         */
        public void onItemSelected(AdapterView parent, View v, int pos, long row) {
            SpinnerActivity.this.mPos = pos;
            SpinnerActivity.this.mSelection = parent.getItemAtPosition(pos).toString();
            /*
             * Set the value of the text field in the UI
             */
            TextView resultText = (TextView)findViewById(R.id.SpinnerResult);
            resultText.setText(SpinnerActivity.this.mSelection);
        }
        /**
         * The definition of OnItemSelectedListener requires an override
         * of onNothingSelected(), even though this implementation does not use it.
         * @param parent - The View for this Listener
         */
        public void onNothingSelected(AdapterView parent) {
            // do nothing
        }
    }
    /**
     * Restores the current state of the spinner (which item is selected, and the value
     * of that item).
     * Since onResume() is always called when an Activity is starting, even if it is re-displaying
     * after being hidden, it is the best place to restore state.
     *
     * Attempts to read the state from a preferences file. If this read fails,
     * assume it was just installed, so do an initialization. Regardless, change the
     * state of the spinner to be the previous position.
     *
     * @see android.app.Activity#onResume()
     */
    @Override
    public void onResume() {
        /*
         * an override to onResume() must call the super constructor first.
         */
        super.onResume();
        /*
         * Try to read the preferences file. If not found, set the state to the desired initial
         * values.
         */
        if (!readInstanceState(this)) setInitialState();
        /*
         * Set the spinner to the current state.
         */
        Spinner restoreSpinner = (Spinner)findViewById(R.id.Spinner01);
        restoreSpinner.setSelection(getSpinnerPosition());
    }
    /**
     * Store the current state of the spinner (which item is selected, and the value of that item).
     * Since onPause() is always called when an Activity is about to be hidden, even if it is about
     * to be destroyed, it is the best place to save state.
     *
     * Attempt to write the state to the preferences file. If this fails, notify the user.
     *
     * @see android.app.Activity#onPause()
     */
    @Override
    public void onPause() {
        /*
         * an override to onPause() must call the super constructor first.
         */
        super.onPause();
        /*
         * Save the state to the preferences file. If it fails, display a Toast, noting the failure.
         */
        if (!writeInstanceState(this)) {
             Toast.makeText(this,
                     "Failed to write state!", Toast.LENGTH_LONG).show();
          }
    }
    /**
     * Sets the initial state of the spinner when the application is first run.
     */
    public void setInitialState() {
        this.mPos = DEFAULT_POSITION;
    }
    /**
     * Read the previous state of the spinner from the preferences file
     * @param c - The Activity's Context
     */
    public boolean readInstanceState(Context c) {
        /*
         * The preferences are stored in a SharedPreferences file. The abstract implementation of
         * SharedPreferences is a "file" containing a hashmap. All instances of an application
         * share the same instance of this file, which means that all instances of an application
         * share the same preference settings.
         */
        /*
         * Get the SharedPreferences object for this application
         */
        SharedPreferences p = c.getSharedPreferences(PREFERENCES_FILE, MODE_WORLD_READABLE);
        /*
         * Get the position and value of the spinner from the file, or a default value if the
         * key-value pair does not exist.
         */
        this.mPos = p.getInt(POSITION_KEY, SpinnerActivity.DEFAULT_POSITION);
        this.mSelection = p.getString(SELECTION_KEY, "");
        /*
         * SharedPreferences doesn't fail if the code tries to get a non-existent key. The
         * most straightforward way to indicate success is to return the results of a test that
         * SharedPreferences contained the position key.
         */
          return (p.contains(POSITION_KEY));
        }
    /**
     * Write the application's current state to a properties repository.
     * @param c - The Activity's Context
     *
     */
    public boolean writeInstanceState(Context c) {
        /*
         * Get the SharedPreferences object for this application
         */
        SharedPreferences p =
                c.getSharedPreferences(SpinnerActivity.PREFERENCES_FILE, MODE_WORLD_READABLE);
        /*
         * Get the editor for this object. The editor interface abstracts the implementation of
         * updating the SharedPreferences object.
         */
        SharedPreferences.Editor e = p.edit();
        /*
         * Write the keys and values to the Editor
         */
        e.putInt(POSITION_KEY, this.mPos);
        e.putString(SELECTION_KEY, this.mSelection);
        /*
         * Commit the changes. Return the result of the commit. The commit fails if Android
         * failed to commit the changes to persistent storage.
         */
        return (e.commit());
    }
    public int getSpinnerPosition() {
        return this.mPos;
    }
    public void setSpinnerPosition(int pos) {
        this.mPos = pos;
    }
    public String getSpinnerSelection() {
        return this.mSelection;
    }
    public void setSpinnerSelection(String selection) {
        this.mSelection = selection;
    }
}
//
//res\layout\main.xml



    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    
            android:id="@+id/Spinner01"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:drawSelectorOnTop = "true"
        android:prompt = "@string/planet_prompt">
    
    
            android:id="@+id/SpinnerResult" android:text="Result"
        android:layout_height="fill_parent" android:textSize="10pt"
        android:textStyle="bold" android:gravity="center"
        android:layout_width="fill_parent">
    

//
//res\values\strings.xml




    Spinner
    
        Mercury
        Venus
        Earth
        Mars
        Jupiter
        Saturn
        Uranus
        Neptune
        Pluto
    
    Select a planet

//
C:\Java_Dev\sdk\Android\android-sdk\samples\android-13\SpinnerTest\src\com\android\example\spinner\test\SpinnerActivityTest.java
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.example.spinner.test;
import com.android.example.spinner.SpinnerActivity;
import android.app.Instrumentation;
import android.test.ActivityInstrumentationTestCase2;
import android.test.UiThreadTest;
import android.view.KeyEvent;
import android.widget.Spinner;
import android.widget.SpinnerAdapter;
import android.widget.TextView;
/*
 * Tests the example application Spinner. Uses the instrumentation test class
 * ActivityInstrumentationTestCase2 as its base class. The tests include
 *   - test initial conditions
 *   - test the UI
 *   - state management - preserving state after the app is shut down and restarted, preserving
 *     state after the app is hidden (paused) and re-displayed (resumed)
 *
 * Demonstrates the use of JUnit setUp() and assert() methods.
 */
public class SpinnerActivityTest extends ActivityInstrumentationTestCase2 {
    // Number of items in the spinner's backing mLocalAdapter
    public static final int ADAPTER_COUNT = 9;
    // The location of Saturn in the backing mLocalAdapter array (0-based)
    public static final int TEST_POSITION = 5;
    // Set the initial position of the spinner to zero
    public static final int INITIAL_POSITION = 0;
    // The initial position corresponds to Mercury
    public static final String INITIAL_SELECTION = "Mercury";
    // Test values of position and selection for the testStateDestroy test
    public static final int TEST_STATE_DESTROY_POSITION = 2;
    public static final String TEST_STATE_DESTROY_SELECTION = "Earth";
    // Test values of position and selection for the testStatePause test
    public static final int TEST_STATE_PAUSE_POSITION = 4;
    public static final String TEST_STATE_PAUSE_SELECTION = "Jupiter";
    // The Application object for the application under test
    private SpinnerActivity mActivity;
    // String displayed in the spinner in the app under test
    private String mSelection;
    // The currently selected position in the spinner in the app under test
    private int mPos;
    /*
     *  The Spinner object in the app under test. Used with instrumentation to control the
     *  app under test.
     */
    private Spinner mSpinner;
    /*
     * The data backing the Spinner in the app under test.
     */
    private SpinnerAdapter mPlanetData;
    /*
     * Constructor for the test class. Required by Android test classes. The constructor
     * must call the super constructor, providing the Android package name of the app under test
     * and the Java class name of the activity in that application that handles the MAIN intent.
     */
    public SpinnerActivityTest() {
        super("com.android.example.spinner", SpinnerActivity.class);
    }
    /*
     * Sets up the test environment before each test.
     * @see android.test.ActivityInstrumentationTestCase2#setUp()
     */
    @Override
    protected void setUp() throws Exception {
        /*
         * Call the super constructor (required by JUnit)
         */
        super.setUp();
        /*
         * prepare to send key events to the app under test by turning off touch mode.
         * Must be done before the first call to getActivity()
         */
        setActivityInitialTouchMode(false);
        /*
         * Start the app under test by starting its main activity. The test runner already knows
         * which activity this is from the call to the super constructor, as mentioned
         * previously. The tests can now use instrumentation to directly access the main
         * activity through mActivity.
         */
        mActivity = getActivity();
        /*
         * Get references to objects in the application under test. These are
         * tested to ensure that the app under test has initialized correctly.
         */
        mSpinner = (Spinner)mActivity.findViewById(com.android.example.spinner.R.id.Spinner01);
        mPlanetData = mSpinner.getAdapter();
    }
    /*
     * Tests the initial values of key objects in the app under test, to ensure the initial
     * conditions make sense. If one of these is not initialized correctly, then subsequent
     * tests are suspect and should be ignored.
     */
    public void testPreconditions() {
        /*
         *  An example of an initialization test. Assert that the item select listener in
         *  the main Activity is not null (has been set to a valid callback)
         */
        assertTrue(mSpinner.getOnItemSelectedListener() != null);
        /*
         * Test that the spinner's backing mLocalAdapter was initialized correctly.
         */
        assertTrue(mPlanetData != null);
        /*
         *  Also ensure that the backing mLocalAdapter has the correct number of entries.
         */
        assertEquals(mPlanetData.getCount(), ADAPTER_COUNT);
    }
    /*
     * Tests the UI of the main activity. Sends key events (keystrokes) to the UI, then checks
     * if the resulting spinner state is consistent with the attempted selection.
     */
    public void testSpinnerUI() {
        /*
         * Request focus for the spinner widget in the application under test,
         * and set its initial position. This code interacts with the app's View
         *  so it has to run on the app's thread not the test's thread.
         *
         * To do this, pass the necessary code to the application with
         * runOnUiThread(). The parameter is an anonymous Runnable object that
         * contains the Java statements put in it by its run() method.
         */
        mActivity.runOnUiThread(
            new Runnable() {
                public void run() {
                    mSpinner.requestFocus();
                    mSpinner.setSelection(INITIAL_POSITION);
                }
            }
        );
        // Activate the spinner by clicking the center keypad key
        this.sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
        // send 5 down arrow keys to the spinner
        for (int i = 1; i <= TEST_POSITION; i++) {
            this.sendKeys(KeyEvent.KEYCODE_DPAD_DOWN);
        }
        // select the item at the current spinner position
        this.sendKeys(KeyEvent.KEYCODE_DPAD_CENTER);
        // get the position of the selected item
        mPos = mSpinner.getSelectedItemPosition();
        /*
         * from the spinner's data mLocalAdapter, get the object at the selected position
         * (this is a String value)
         */
        mSelection = (String)mSpinner.getItemAtPosition(mPos);
        /*
         * Get the TextView widget that displays the result of selecting an item from the spinner
         */
        TextView resultView =
                (TextView) mActivity.findViewById(com.android.example.spinner.R.id.SpinnerResult);
        // Get the String value in the EditText object
        String resultText = (String) resultView.getText();
        /*
         * Confirm that the EditText contains the same value as the data in the mLocalAdapter
         */
        assertEquals(resultText,mSelection);
    }
    /*
     *  Tests that the activity under test maintains the spinner state when the activity halts
     *  and then restarts (for example, if the device reboots). Sets the spinner to a
     *  certain state, calls finish() on the activity, restarts the activity, and then
     *  checks that the spinner has the same state.
     *
     */
    public void testStateDestroy() {
        /*
         * Set the position and value of the spinner in the Activity. The test runner's
         * instrumentation enables this by running the test app and the main app in the same
         * process.
         */
        mActivity.setSpinnerPosition(TEST_STATE_DESTROY_POSITION);
        mActivity.setSpinnerSelection(TEST_STATE_DESTROY_SELECTION);
        // Halt the Activity by calling Activity.finish() on it
        mActivity.finish();
        // Restart the activity by calling ActivityInstrumentationTestCase2.getActivity()
        mActivity = this.getActivity();
        /*
         * Get the current position and selection from the activity.
         */
        int currentPosition = mActivity.getSpinnerPosition();
        String currentSelection = mActivity.getSpinnerSelection();
        // test that they are the same.
        assertEquals(TEST_STATE_DESTROY_POSITION, currentPosition);
        assertEquals(TEST_STATE_DESTROY_SELECTION, currentSelection);
    }
    /*
     * Tests that the activity under test maintains the spinner's state when the activity is
     * paused and then resumed.
     *
     * Calls the activity's onResume() method. Changes the spinner's state by
     * altering the activity's View. This means the test must run
     * on the UI Thread. All the statements in the test method may be run on
     * that thread, so instead of using the runOnUiThread() method, the
     * @UiThreadTest is used.
     */
    @UiThreadTest
    public void testStatePause() {
        /*
         * Get the instrumentation object for this application. This object
         * does all the instrumentation work for the test runner
         */
        Instrumentation instr = this.getInstrumentation();
        /*
         * Set the activity's fields for the position and value of the spinner
         */
        mActivity.setSpinnerPosition(TEST_STATE_PAUSE_POSITION);
        mActivity.setSpinnerSelection(TEST_STATE_PAUSE_SELECTION);
        /*
         *  Use the instrumentation to onPause() on the currently running Activity.
         *  This analogous to calling finish() in the testStateDestroy() method.
         *  This way demonstrates using the test class' instrumentation.
         */
        instr.callActivityOnPause(mActivity);
        /*
         * Set the spinner to a test position
         */
        mActivity.setSpinnerPosition(0);
        mActivity.setSpinnerSelection("");
        /*
         * Call the activity's onResume() method. This forces the activity
         * to restore its state.
         */
        instr.callActivityOnResume(mActivity);
        /*
         * Get the current state of the spinner
         */
        int currentPosition = mActivity.getSpinnerPosition();
        String currentSelection = mActivity.getSpinnerSelection();
        assertEquals(TEST_STATE_PAUSE_POSITION,currentPosition);
        assertEquals(TEST_STATE_PAUSE_SELECTION,currentSelection);
  }
}
//
C:\Java_Dev\sdk\Android\android-sdk\samples\android-13\SpinnerTest\res\values\strings.xml




    SpinnerTest