summaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
authorScott Main <smain@google.com>2010-01-19 19:59:24 -0800
committerAndroid Git Automerger <android-git-automerger@android.com>2010-01-19 19:59:24 -0800
commit382f924c951ff49e9bbb48a744a45fce1ad7ccd4 (patch)
treef3d8ba1e322a02572eba0b9edfce8bdaf5791838 /docs
parent97b108532f04f72af035e372be7b827f77888650 (diff)
parent5615ca1979caa79041bf16a2cae49f9cfadd7ee5 (diff)
downloadframeworks_base-382f924c951ff49e9bbb48a744a45fce1ad7ccd4.zip
frameworks_base-382f924c951ff49e9bbb48a744a45fce1ad7ccd4.tar.gz
frameworks_base-382f924c951ff49e9bbb48a744a45fce1ad7ccd4.tar.bz2
am 5615ca19: docs: a lot of revision and expansion of the hello view tutorials includes new screenshots for some tutorials and a new sample images zip file
Merge commit '5615ca1979caa79041bf16a2cae49f9cfadd7ee5' into eclair-plus-aosp * commit '5615ca1979caa79041bf16a2cae49f9cfadd7ee5': docs: a lot of revision and expansion of the hello view tutorials
Diffstat (limited to 'docs')
-rw-r--r--docs/html/resources/tutorials/views/hello-autocomplete.jd107
-rw-r--r--docs/html/resources/tutorials/views/hello-datepicker.jd144
-rw-r--r--docs/html/resources/tutorials/views/hello-formstuff.jd380
-rw-r--r--docs/html/resources/tutorials/views/hello-gallery.jd116
-rw-r--r--docs/html/resources/tutorials/views/hello-gridview.jd119
-rw-r--r--docs/html/resources/tutorials/views/hello-linearlayout.jd191
-rw-r--r--docs/html/resources/tutorials/views/hello-listview.jd120
-rw-r--r--docs/html/resources/tutorials/views/hello-mapview.jd426
-rw-r--r--docs/html/resources/tutorials/views/hello-relativelayout.jd52
-rw-r--r--docs/html/resources/tutorials/views/hello-spinner.jd121
-rw-r--r--docs/html/resources/tutorials/views/hello-tablelayout.jd30
-rw-r--r--docs/html/resources/tutorials/views/hello-tabwidget.jd220
-rw-r--r--docs/html/resources/tutorials/views/hello-timepicker.jd182
-rw-r--r--docs/html/resources/tutorials/views/hello-webview.jd175
-rw-r--r--docs/html/resources/tutorials/views/images/android_focused.pngbin0 -> 2785 bytes
-rw-r--r--docs/html/resources/tutorials/views/images/android_normal.pngbin0 -> 2056 bytes
-rw-r--r--docs/html/resources/tutorials/views/images/android_pressed.pngbin0 -> 2337 bytes
-rw-r--r--[-rwxr-xr-x]docs/html/resources/tutorials/views/images/hello-autocomplete.pngbin4601 -> 17719 bytes
-rw-r--r--[-rwxr-xr-x]docs/html/resources/tutorials/views/images/hello-formstuff.pngbin4258 -> 23272 bytes
-rw-r--r--[-rwxr-xr-x]docs/html/resources/tutorials/views/images/hello-listview.pngbin6926 -> 26359 bytes
-rw-r--r--[-rwxr-xr-x]docs/html/resources/tutorials/views/images/hello-mapview.pngbin16922 -> 50499 bytes
-rw-r--r--docs/html/resources/tutorials/views/images/hello-tabwidget.pngbin2117 -> 10393 bytes
-rw-r--r--[-rwxr-xr-x]docs/html/resources/tutorials/views/images/hello-webview.pngbin5874 -> 16490 bytes
-rw-r--r--docs/html/resources/tutorials/views/images/ic_tab_artists_grey.pngbin0 -> 791 bytes
-rw-r--r--docs/html/resources/tutorials/views/images/ic_tab_artists_white.pngbin0 -> 1127 bytes
-rw-r--r--docs/html/resources/tutorials/views/index.jd127
-rw-r--r--docs/html/shareables/sample_images.zipbin0 -> 254816 bytes
27 files changed, 1537 insertions, 973 deletions
diff --git a/docs/html/resources/tutorials/views/hello-autocomplete.jd b/docs/html/resources/tutorials/views/hello-autocomplete.jd
index fba1ad8..e26683d 100644
--- a/docs/html/resources/tutorials/views/hello-autocomplete.jd
+++ b/docs/html/resources/tutorials/views/hello-autocomplete.jd
@@ -1,56 +1,82 @@
-page.title=Hello, AutoCompleteTextView
+page.title=Auto Complete
parent.title=Hello, Views
parent.link=index.html
@jd:body
-<p>{@link android.widget.AutoCompleteTextView} is an implementation of the EditText widget that will provide
-auto-complete suggestions as the user types. The suggestions are extracted from a collection of strings.</p>
+<p>To create a text entry widget that provides auto-complete suggestions, use
+the {@link android.widget.AutoCompleteTextView} widget. Suggestions are received from a
+collection of strings associated with the widget through an {@link
+android.widget.ArrayAdapter}.</p>
+
+<p>In this tutorial, you will create a {@link android.widget.AutoCompleteTextView} widget that
+provides suggestions for a country name.</p>
<ol>
- <li>Start a new project/Activity called HelloAutoComplete.</li>
- <li>Open the layout file.
- Make it like so:
+ <li>Start a new project named <em>HelloAutoComplete</em>.</li>
+ <li>Create an XML file named <code>list_item.xml</code> and save it inside the
+<code>res/layout/</code> folder. Edit the file to look like this:
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:padding="10dp"
+ android:textSize="16sp"
+ android:textColor="#000">
+&lt;/TextView>
+</pre>
+ <p>This file defines a simple {@link android.widget.TextView} that will be used for each
+item that appears in the list of suggestions.</p>
+ </li>
+ <li>Open the <code>res/layout/main.xml</code> file and insert the following:
<pre>
&lt;?xml version="1.0" encoding="utf-8"?>
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
- android:layout_height="wrap_content">
-
+ android:layout_height="wrap_content"
+ android:padding="5dp">
&lt;TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Country" />
-
- &lt;AutoCompleteTextView android:id="@+id/edit"
+ &lt;AutoCompleteTextView android:id="@+id/autocomplete_country"
android:layout_width="fill_parent"
- android:layout_height="wrap_content"/>
-
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="5dp"/>
&lt;/LinearLayout>
</pre>
+ <p>The {@link android.widget.TextView} is a label that introduces the {@link
+android.widget.AutoCompleteTextView} widget.
</li>
-<li>Open HelloAutoComplete.java and insert the following as the <code>onCreate</code> method:
+<li>Open <code>HelloAutoComplete.java</code> and insert the following code for the {@link
+android.app.Activity#onCreate(Bundle) onCreate()} method:
<pre>
&#64;Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
- AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.edit);
- ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
- android.R.layout.simple_dropdown_item_1line, COUNTRIES);
+ AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.autocomplete_country);
+ ArrayAdapter&lt;String> adapter = new ArrayAdapter&lt;String>(this, R.layout.list_item, COUNTRIES);
textView.setAdapter(adapter);
}
</pre>
- <p>Here, we create an AutoComplteteTextView from our layout. We then
- create an {@link android.widget.ArrayAdapter} that binds a <code>simple_dropdown_item_1line</code>
- layout item to each entry in the <code>COUNTRIES</code> array (which we'll add next).
- The last part sets the ArrayAdapter to associate with our AutoCompleteTextView.</p>
+
+<p>After the content view is set to the <code>main.xml</code> layout, the {@link
+android.widget.AutoCompleteTextView} widget is captured from the layout with {@link
+android.app.Activity#findViewById(int)}. A new {@link
+android.widget.ArrayAdapter} is then initialized to bind the <code>list_item.xml</code> layout
+to each list item in the <code>COUNTRIES</code> string array (defined in the next step).
+Finally, {@link android.widget.AutoCompleteTextView#setAdapter(T) setAdapter()} is called to
+associate the {@link android.widget.ArrayAdapter} with the
+{@link android.widget.AutoCompleteTextView} widget so that the string array will populate
+the list of suggestions.</p>
</li>
-<li>After the <code>onCreate()</code> method, add the String array:
+<li>Inside the <code>HelloAutoComplete</code> class, add the string array:
<pre>
static final String[] COUNTRIES = new String[] {
"Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra",
@@ -96,19 +122,50 @@ static final String[] COUNTRIES = new String[] {
"Yemen", "Yugoslavia", "Zambia", "Zimbabwe"
};
</pre>
- <p>This is the list of suggestions that will be offered as the user types into the
- AutoCompleteTextView.</p>
+<p>This is the list of suggestions that will be provided in a drop-down list when the user types into
+the {@link android.widget.AutoCompleteTextView} widget.</p>
</li>
-<li>Now run it.</li>
+<li>Run the application.</li>
</ol>
<p>As you type, you should see something like this:</p>
<img src="images/hello-autocomplete.png" width="150px" />
+<h2>More Information</h2>
+
+<p>Note that using a hard-coded string array is not a recommended design practice because your
+application code should focus on behavior, not content. Application content such as strings
+should be externalized from the code in order to make modifications to the content easier and
+facilitate localization of the content. The hard-coded strings are used in this tutorial only to
+make it simple and focus on the {@link android.widget.AutoCompleteTextView} widget.
+Instead, your application should declare such string arrays in an XML file. This can be done
+with a {@code &lt;string-array&lt;} resource in your project {@code res/values/strings.xml} file.
+For example:</p>
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;resources>
+ &lt;string-array name="countries_array">
+ &lt;item>Bahrain&lt;/item>
+ &lt;item>Bangladesh&lt;/item>
+ &lt;item>Barbados&lt;/item>
+ &lt;item>Belarus&lt;/item>
+ &lt;item>Belgium&lt;/item>
+ &lt;item>Belize&lt;/item>
+ &lt;item>Benin&lt;/item>
+ &lt;/string-array>
+&lt;/resources>
+</pre>
+<p>To use these resource strings for the {@link android.widget.ArrayAdapter}, replace the original
+{@link android.widget.ArrayAdapter} constructor line with the following:</p>
+<pre>
+String[] countries = getResources().getStringArray(R.array.countries_array);
+ArrayAdapter&lt;String> adapter = new ArrayAdapter&lt;String>(this, R.layout.list_item, countries);
+</pre>
+
+
<h3>References</h3>
<ul>
- <li>{@link android.R.layout}</li>
<li>{@link android.widget.ArrayAdapter}</li>
<li>{@link android.widget.AutoCompleteTextView}</li>
</ul>
diff --git a/docs/html/resources/tutorials/views/hello-datepicker.jd b/docs/html/resources/tutorials/views/hello-datepicker.jd
index fcd43f3..c50d650 100644
--- a/docs/html/resources/tutorials/views/hello-datepicker.jd
+++ b/docs/html/resources/tutorials/views/hello-datepicker.jd
@@ -1,52 +1,57 @@
-page.title=Hello, DatePicker
+page.title=Date Picker
parent.title=Hello, Views
parent.link=index.html
@jd:body
-<p>A {@link android.widget.DatePicker} is a widget that allows the user to select a month, day and year.</p>
+<p>To provide a widget for selecting a date, use the {@link android.widget.DatePicker}
+widget, which allows the user to select the month, day, and year, in a familiar interface.</p>
+<p>In this tutorial, you'll create a {@link android.app.DatePickerDialog}, which presents the
+date picker in a floating dialog box at the press of a button. When the date is set by
+the user, a {@link android.widget.TextView} will update with the new date.</p>
<ol>
- <li>Start a new project/Activity called HelloDatePicker.</li>
- <li>Open the layout file and make it like so:
- <pre>
+ <li>Start a new project named <em>HelloDatePicker</em>.</li>
+ <li>Open the <code>res/layout/main.xml</code> file and insert the following:
+<pre>
&lt;?xml version="1.0" encoding="utf-8"?>
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
-
&lt;TextView android:id="@+id/dateDisplay"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text=""/>
-
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text=""/>
&lt;Button android:id="@+id/pickDate"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Change the date"/>
-
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Change the date"/>
&lt;/LinearLayout>
</pre>
- <p>For the layout, we're using a vertical LinearLayout, with a {@link android.widget.TextView} that
- will display the date and a {@link android.widget.Button} that will initiate the DatePicker dialog.
- With this layout, the TextView will sit above the Button.
- The text value in the TextView is set empty, as it will be filled
- with the current date when our Activity runs.</p>
- </li>
-
- <li>Open HelloDatePicker.java. Insert the following to the HelloDatePicker class:
+ <p>This creates a basic {@link android.widget.LinearLayout} with a {@link android.widget.TextView}
+ that will display the date and a {@link android.widget.Button} that will open the {@link
+ android.app.DatePickerDialog}.</p>
+ </li>
+
+ <li>Open <code>HelloDatePicker.java</code> and add the following members to the class:
<pre>
private TextView mDateDisplay;
private Button mPickDate;
-
private int mYear;
private int mMonth;
private int mDay;
static final int DATE_DIALOG_ID = 0;
+</pre>
+ <p>The first group of members define variables for the layout {@link android.view.View}s and the
+date items. The <code>DATE_DIALOG_ID</code> is a static integer that uniquely identifies the {@link
+android.app.Dialog} that will display the date picker.</p>
+ </li>
- &#64;Override
+ <li>Now add the following code for the {@link android.app.Activity#onCreate(Bundle) onCreate()}
+method:
+<pre>
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
@@ -68,43 +73,30 @@ parent.link=index.html
mMonth = c.get(Calendar.MONTH);
mDay = c.get(Calendar.DAY_OF_MONTH);
- // display the current date
+ // display the current date (this method is below)
updateDisplay();
}
</pre>
-<p class="note"><strong>Tip:</strong> Press Ctrl(or Cmd) + Shift + O to import all needed packages.</p>
- <p>We start by instantiating variables for our Views and date fields.
- The <code>DATE_DIALOG_ID</code> is a static integer that uniquely identifies the Dialog. In the
- <code>onCreate()</code> method, we get prepared by setting the layout and capturing the View elements.
- Then we create an on-click listener for the Button, so that when it is clicked it will
- show our DatePicker dialog. The <code>showDialog()</code> method will pop-up the date picker dialog
- by calling the <code>onCreateDialog()</code> callback method
- (which we'll define in the next section). We then create an
- instance of {@link java.util.Calendar} and get the current year, month and day. Finally, we call
- <code>updateDisplay()</code>&mdash;our own method (defined later) that will fill the TextView.</p>
-</li>
-<li>After the <code>onCreate()</code> method, add the <code>onCreateDialog()</code> callback method
-(which is called by <code>showDialog()</code>)
-<pre>
-&#64;Override
-protected Dialog onCreateDialog(int id) {
- switch (id) {
- case DATE_DIALOG_ID:
- return new DatePickerDialog(this,
- mDateSetListener,
- mYear, mMonth, mDay);
- }
- return null;
-}
-</pre>
- <p>This method is passed the identifier we gave <code>showDialog()</code> and initializes
- the DatePicker to the date we retrieved from our Calendar instance.</p>
+<p>First, the content is set to the <code>main.xml</code> layout. Then the {@link
+android.widget.TextView} and {@link android.widget.Button} elements are captured from the layout
+with {@link android.app.Activity#findViewById(int)}. A
+new {@link android.view.View.OnClickListener} is created for the
+{@link android.widget.Button}, so that when it is clicked, it
+will call {@link android.app.Activity#showDialog(int)}, passing the unique integer ID for
+the date picker dialog. Using {@link android.app.Activity#showDialog(int)} allows the {@link
+android.app.Activity} to manage the life-cycle of the dialog and will call the {@link
+android.app.Activity#onCreateDialog(int)} callback method to request the {@link android.app.Dialog}
+that should be displayed (which you'll
+define later). After the on-click listener is set, a new {@link java.util.Calendar} is created
+and the current year, month and day are acquired. Finally, the private
+<code>updateDisplay()</code> method is called in order to fill the {@link android.widget.TextView}
+with the current date.</p>
</li>
-<li>Following that, add the <code>updateDisplay()</code> method:
+<li>Add the <code>updateDisplay()</code> method:
<pre>
- // updates the date we display in the TextView
+ // updates the date in the TextView
private void updateDisplay() {
mDateDisplay.setText(
new StringBuilder()
@@ -114,9 +106,13 @@ protected Dialog onCreateDialog(int id) {
.append(mYear).append(" "));
}
</pre>
-<p>This uses the member date values to write the date to our TextView.</p>
+<p>This method uses the member date values declared for the class to write the date to the layout's
+{@link android.widget.TextView}, {@code mDateDisplay}, which was also declared and initialized
+above.</p>
</li>
-<li>Finally, add a listener that will be called when the user sets a new date:
+
+<li>Initialize a new {@link android.app.DatePickerDialog.OnDateSetListener} as a member of the
+<code>HelloDatePicker</code> class:
<pre>
// the callback received when the user "sets" the date in the dialog
private DatePickerDialog.OnDateSetListener mDateSetListener =
@@ -131,19 +127,45 @@ protected Dialog onCreateDialog(int id) {
}
};
</pre>
- <p>This <code>OnDateSetListener</code> method listens for when the user is done setting the date
- (clicks the "Set" button). At that time, this fires and we update our member fields with
- the new date defined by the user and update our TextView by calling <code>updateDisplay()</code>.</p>
+<p>The {@link android.app.DatePickerDialog.OnDateSetListener} listens for when the user
+has set the date (by clicking the "Set" button). At that time, the {@link
+android.app.DatePickerDialog.OnDateSetListener#onDateSet(DatePicker,int,int,int) onDateSet()}
+callback method is called, which is defined to update the {@code mYear}, {@code mMonth}, and
+{@code mDay} member fields with the new date then call the private <code>updateDisplay()</code>
+method to update the {@link android.widget.TextView}.</p>
+</li>
+
+<li>Now add the {@link android.app.Activity#onCreateDialog(int)} callback method to the {@code
+HelloDatePicker} class:
+<pre>
+&#64;Override
+protected Dialog onCreateDialog(int id) {
+ switch (id) {
+ case DATE_DIALOG_ID:
+ return new DatePickerDialog(this,
+ mDateSetListener,
+ mYear, mMonth, mDay);
+ }
+ return null;
+}
+</pre>
+<p>This is an {@link android.app.Activity} callback method that is passed the integer ID given to
+{@link android.app.Activity#showDialog(int)} (which is called by the button's {@link
+android.view.View.OnClickListener}). When the ID matches the switch case defined here, a {@link
+android.app.DatePickerDialog} is instantiated with the {@link
+android.app.DatePickerDialog.OnDateSetListener} created in the previous
+step, along with the date variables to initialize the widget date.</p>
</li>
-<li>Now run it.</li>
+<li>Run the application.</li>
</ol>
<p>When you press the "Change the date" button, you should see the following:</p>
<img src="images/hello-datepicker.png" width="150px" />
<h3>References</h3>
<ul>
-<li>{@link android.widget.DatePicker}</li>
+<li>{@link android.app.DatePickerDialog}</li>
+<li>{@link android.app.DatePickerDialog.OnDateSetListener}</li>
<li>{@link android.widget.Button}</li>
<li>{@link android.widget.TextView}</li>
<li>{@link java.util.Calendar}</li>
diff --git a/docs/html/resources/tutorials/views/hello-formstuff.jd b/docs/html/resources/tutorials/views/hello-formstuff.jd
index da4289c..3dd5f21 100644
--- a/docs/html/resources/tutorials/views/hello-formstuff.jd
+++ b/docs/html/resources/tutorials/views/hello-formstuff.jd
@@ -1,58 +1,99 @@
-page.title=Hello, Form Stuff
+page.title=Form Stuff
parent.title=Hello, Views
parent.link=index.html
@jd:body
-<p>This page introduces a variety of widgets, like image buttons,
-text fields, checkboxes and radio buttons.</p>
+<p>This tutorial introduces a variety of widgets that are useful when creating forms, such as
+image buttons, text fields, checkboxes and radio buttons.</p>
<ol>
- <li>Start a new project/Activity called HelloFormStuff.</li>
- <li>Your layout file should have a basic LinearLayout:
- <pre>
+ <li>Start a new project named <em>HelloFormStuff</em>.</li>
+ <li>Your <code>res/layout/main.xml</code> file should already have a basic {@link
+android.widget.LinearLayout}:
+<pre>
&lt;?xml version="1.0" encoding="utf-8"?>
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
-
&lt;/LinearLayout>
</pre>
- <p>For each widget you want to add, just put the respective View inside here.</p>
-</li>
+ <p>For each widget you want to add, just put the respective View inside this {@link
+android.widget.LinearLayout}.</p>
+ </li>
</ol>
-<p class="note"><strong>Tip:</strong> As you add new Android code, press Ctrl(or Cmd) + Shift + O
-to import all needed packages.</p>
+<p>Each section below also assumes that your <code>HelloFormStuff</code> Activity has the following
+default implementation of the {@link android.app.Activity#onCreate(Bundle) onCreate()} method:</p>
+<pre>
+public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+}
+</pre>
+
+
+<h2>Custom Button</h2>
-<h2>ImageButton</h2>
-<p>A button with a custom image on it.
-We'll make it display a message when pressed.</p>
+<p>In this section, you will create a button with a custom image instead of text, using the {@link
+android.widget.Button} widget and an XML file that defines three different images to use for the
+different button states. When the button is pressed, a short message will be displayed.</p>
+
+<img src="images/android_pressed.png" style="float:right;" title="android_pressed.png"/>
+<img src="images/android_focused.png" style="float:right;clear:right;" title="android_focused.png"/>
+<img src="images/android_normal.png" style="float:right;clear:right;" title="android_normal.png"/>
<ol>
- <li><img src="images/android.png" align="right"/>
- Drag the Android image on the right (or your own image) into the
- res/drawable/ directory of your project.
- We'll use this for the button.</li>
- <li>Open the layout file and, inside the LinearLayout, add the {@link android.widget.ImageButton} element:
+ <li>Copy the images on the right into the <code>res/drawable/</code> directory of
+your project. These will be used for the different button states.</li>
+ <li>Create a new file in the <code>res/drawable/</code> directory named
+<code>android_button.xml</code>.
+Insert the following XML:
<pre>
-&lt;ImageButton
- android:id="@+id/android_button"
- android:layout_width="100dip"
- android:layout_height="wrap_content"
- android:src="@drawable/android" />
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;selector xmlns:android="http://schemas.android.com/apk/res/android">
+ &lt;item android:drawable="@drawable/android_pressed"
+ android:state_pressed="true" />
+ &lt;item android:drawable="@drawable/android_focused"
+ android:state_focused="true" />
+ &lt;item android:drawable="@drawable/android_normal" />
+&lt;/selector>
</pre>
- <p>The source of the button
- is from the res/drawable/ directory, where we've placed the android.png.</p>
- <p class="note"><strong>Tip:</strong> You can also reference some of the many built-in
- images from the Android {@link android.R.drawable} resources,
- like <code>ic_media_play</code>, for a "play" button image. To do so, change the source
- attribute to <code>android:src="@android:drawable/ic_media_play"</code>.</p>
+ <p>This defines a single drawable resource, which will change its image based on the current
+state of the button. The first <code>&lt;item></code> defines
+<code>android_pressed.png</code> as the image when the button is pressed (it's been
+activated); the second <code>&lt;item></code> defines <code>android_focused.png</code> as the image
+when the button is focused (when the button is highlighted using the trackball or directional
+pad); and the third <code>&lt;item></code> defines <code>android_normal.png</code> as the image
+for the normal state (when neither pressed nor focused). This XML file now represents a single
+drawable resource and when referenced by a {@link android.widget.Button} for its background,
+the image displayed will change based on these three states.</p>
+ <p class="note"><strong>Note:</strong> The order of the <code>&lt;item></code> elements is
+important. When this drawable is referenced, the <code>&lt;item></code>s are traversed in-order to
+determine which one is appropriate for the current button state. Because the "normal" image is last,
+it is only applied when the conditions <code>android:state_pressed</code> and
+<code>android:state_focused</code> have both evaluated false.</li>
+ <li>Open the <code>res/layout/main.xml</code> file and add the {@link
+android.widget.Button} element:
+<pre>
+ &lt;Button
+ android:id="@+id/button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:padding="10dp"
+ android:background="@drawable/android_button" />
+</pre>
+ <p>The <code>android:background</code> attribute specifies the drawable resource to use for the
+button background (which, when saved at <code>res/drawable/android.xml</code>, is
+referenced as <code>@drawable/android</code>). This replaces the normal background image
+used for buttons throughout the system. In order for the drawable to change its image based on
+the button state, the image must be applied to the background.</p>
</li>
-<li>To make the button to actually do something, add the following
-code at the end of the <code>onCreate()</code> method:
+
+<li>To make the button do something when pressed, add the following
+code at the end of the {@link android.app.Activity#onCreate(Bundle) onCreate()} method:
<pre>
-final ImageButton button = (ImageButton) findViewById(R.id.android_button);
+final Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// Perform action on clicks
@@ -60,34 +101,41 @@ button.setOnClickListener(new OnClickListener() {
}
});
</pre>
-<p>This captures our ImageButton from the layout, then adds an on-click listener to it.
-The {@link android.view.View.OnClickListener} must define the <code>onClick()</code> method, which
-defines the action to be made when the button is clicked. Here, we show a
-{@link android.widget.Toast} message when clicked.</p>
+<p>This captures the {@link android.widget.Button} from the layout, then adds an {@link
+android.view.View.OnClickListener}. The {@link android.view.View.OnClickListener}
+must implement the {@link android.view.View.OnClickListener#onClick(View)} callback method, which
+defines the action to be made when the button is clicked. In this example, a
+{@link android.widget.Toast} message will be displayed.</p>
</li>
-<li>Run it.</li>
+<li>Now run the application.</li>
</ol>
<h2>EditText</h2>
-<p>A text field for user input. We'll make it display the text entered so far when the "Enter" key is pressed.</p>
+
+<p>In this section, you will create a text field for user input, using the {@link
+android.widget.EditText} widget. Once text has been entered into the field, the "Enter" key will
+display the text in a toast message.</p>
<ol>
- <li>Open the layout file and, inside the LinearLayout, add the {@link android.widget.EditText} element:
+ <li>Open the <code>res/layout/main.xml</code> file and add the {@link android.widget.EditText}
+element (inside the {@link android.widget.LinearLayout}):
<pre>
-&lt;EditText
- android:id="@+id/edittext"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"/>
+ &lt;EditText
+ android:id="@+id/edittext"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"/>
</pre>
</li>
-<li>To do something with the text that the user enters, add the following code
-to the end of the <code>onCreate()</code> method:
+<li>To do something with the text that the user types, add the following code
+to the end of the {@link android.app.Activity#onCreate(Bundle) onCreate()} method:
<pre>
final EditText edittext = (EditText) findViewById(R.id.edittext);
edittext.setOnKeyListener(new OnKeyListener() {
public boolean onKey(View v, int keyCode, KeyEvent event) {
- if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
+ // If the event is a key-down event on the "enter" button
+ if ((event.getAction() == KeyEvent.ACTION_DOWN) &amp;&amp;
+ (keyCode == KeyEvent.KEYCODE_ENTER)) {
// Perform action on key press
Toast.makeText(HelloFormStuff.this, edittext.getText(), Toast.LENGTH_SHORT).show();
return true;
@@ -96,37 +144,44 @@ edittext.setOnKeyListener(new OnKeyListener() {
}
});
</pre>
-<p>This captures our EditText element from the layout, then adds an on-key listener to it.
-The {@link android.view.View.OnKeyListener} must define the <code>onKey()</code> method, which
-defines the action to be made when a key is pressed. In this case, we want to listen for the
-Enter key (when pressed down), then pop up a {@link android.widget.Toast} message with the
-text from the EditText field. Be sure to return <var>true</var> after the event is handled,
-so that the event doesn't bubble-up and get handled by the View (which would result in a
-carriage return in the text field).</p>
-<li>Run it.</li>
+<p>This captures the {@link android.widget.EditText} element from the layout and adds an {@link
+android.view.View.OnKeyListener}. The {@link android.view.View.OnKeyListener} must implement the
+{@link android.view.View.OnKeyListener#onKey(View,int,KeyEvent)} method, which
+defines the action to be made when a key is pressed while the widget has focus. In this case, the
+method is defined to listen for the Enter key (when pressed down), then pop up a {@link
+android.widget.Toast} message with the text that has been entered. The {@link
+android.view.View.OnKeyListener#onKey(View,int,KeyEvent)} method should always return
+<code>true</code> if the event has been handled, so that the event doesn't bubble-up (which would
+result in a carriage return in the text field).</p>
+</li>
+<li>Run the application.</li>
</ol>
<h2>CheckBox</h2>
-<p>A checkbox for selecting items. We'll make it display the the current state when pressed.</p>
+
+<p>In this section, you will create a checkbox for selecting items, using the {@link
+android.widget.CheckBox} widget. When the checkbox is pressed, a toast message will
+indicate the current state of the checkbox.</p>
<ol>
- <li>Open the layout file and, inside the LinearLayout, add the {@link android.widget.CheckBox} element:
+ <li>Open the <code>res/layout/main.xml</code> file and add the {@link android.widget.CheckBox}
+element (inside the {@link android.widget.LinearLayout}):
<pre>
-&lt;CheckBox android:id="@+id/checkbox"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="check it out" />
+ &lt;CheckBox android:id="@+id/checkbox"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="check it out" />
</pre>
</li>
<li>To do something when the state is changed, add the following code
-to the end of the <code>onCreate()</code> method:
+to the end of the {@link android.app.Activity#onCreate(Bundle) onCreate()} method:
<pre>
final CheckBox checkbox = (CheckBox) findViewById(R.id.checkbox);
checkbox.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
- // Perform action on clicks
- if (checkbox.isChecked()) {
+ // Perform action on clicks, depending on whether it's now checked
+ if (((CheckBox) v).isChecked()) {
Toast.makeText(HelloFormStuff.this, "Selected", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(HelloFormStuff.this, "Not selected", Toast.LENGTH_SHORT).show();
@@ -134,52 +189,62 @@ checkbox.setOnClickListener(new OnClickListener() {
}
});
</pre>
-<p>This captures our CheckBox element from the layout, then adds an on-click listener to it.
-The {@link android.view.View.OnClickListener} must define the <code>onClick()</code> method, which
-defines the action to be made when the checkbox is clicked. Here, we query the current state of the
-checkbox, then pop up a {@link android.widget.Toast} message that displays the current state.
-Notice that the CheckBox handles its own state change between checked and un-checked, so we just
-ask which it currently is.</p>
+<p>This captures the {@link android.widget.CheckBox} element from the layout, then adds an {@link
+android.view.View.OnClickListener}. The {@link android.view.View.OnClickListener} must implement the
+{@link android.view.View.OnClickListener#onClick(View)} callback method, which
+defines the action to be made when the checkbox is clicked. When clicked, {@link
+android.widget.CompoundButton#isChecked()} is called to check the new state of the check box. If it
+has been checked, then a {@link android.widget.Toast} displays the message "Selected", otherwise it
+displays "Not selected". Note that the {@link android.view.View} object that is passed in the {@link
+android.view.View.OnClickListener#onClick(View)} callback must be cast to a {@link
+android.widget.CheckBox} because the {@link android.widget.CompoundButton#isChecked()} method is
+not defined by the parent {@link android.view.View} class. The {@link android.widget.CheckBox}
+handles its own state changes, so you only need to query the current state.</p>
+</li>
<li>Run it.</li>
</ol>
-<p class="note"><strong>Tip:</strong> If you find that you need to change the state
-in another way (such as when loading a saved {@link android.preference.CheckBoxPreference}),
-use <code>setChecked(true)</code> or <code>toggle()</code>.</p>
+<p class="note"><strong>Tip:</strong> If you need to change the state
+yourself (such as when loading a saved {@link android.preference.CheckBoxPreference}),
+use the {@link android.widget.CompoundButton#setChecked(boolean)} or {@link
+android.widget.CompoundButton#toggle()} method.</p>
<h2>RadioButton</h2>
-<p>Two mutually-exclusive radio buttons&mdash;enabling one disables the other.
-When each is pressed, we'll pop up a message.</p>
+
+<p>In this section, you will create two mutually-exclusive radio buttons (enabling one disables
+the other), using the {@link android.widget.RadioGroup} and {@link android.widget.RadioButton}
+widgets. When either radio button is pressed, a toast message will be displayed.</p>
<ol>
- <li>Open the layout file and, inside the LinearLayout, add two {@link android.widget.RadioButton}s,
-inside a {@link android.widget.RadioGroup}:
+ <li>Open the <code>res/layout/main.xml</code> file and add two {@link
+android.widget.RadioButton}s, nested in a {@link android.widget.RadioGroup} (inside the {@link
+android.widget.LinearLayout}):
<pre>
-&lt;RadioGroup
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical">
-
- &lt;RadioButton android:id="@+id/radio_red"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="Red" />
-
- &lt;RadioButton android:id="@+id/radio_blue"
- android:layout_width="wrap_content"
+ &lt;RadioGroup
+ android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:text="Blue" />
-
-&lt;/RadioGroup>
+ android:orientation="vertical">
+ &lt;RadioButton android:id="@+id/radio_red"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Red" />
+ &lt;RadioButton android:id="@+id/radio_blue"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Blue" />
+ &lt;/RadioGroup>
</pre>
+<p>It's important that the {@link android.widget.RadioButton}s are grouped together by the {@link
+android.widget.RadioGroup} element so that no more than one can be selected at a time. This logic
+is automatically handled by the Android system. When one {@link android.widget.RadioButton} within
+a group is selected, all others are automatically deselected.</p>
</li>
-<li>To do something when each is selected, we'll need an OnClickListener. Unlike the other
-listeners we've created, instead of creating this one as an anonymous inner class,
-we'll create it as a new object. This way, we can re-use the OnClickLIstener for
-both RadioButtons. So, add the following code in the HelloFormStuff Activity
-(<em>outside</em> the <code>onCreate()</code> method):
+
+<li>To do something when each {@link android.widget.RadioButton} is selected, you need an
+{@link android.view.View.OnClickListener}. In this case, you want the listener to be re-usable, so
+add the following code to create a new member in the <code>HelloFormStuff</code> Activity:
<pre>
-OnClickListener radio_listener = new OnClickListener() {
+private OnClickListener radio_listener = new OnClickListener() {
public void onClick(View v) {
// Perform action on clicks
RadioButton rb = (RadioButton) v;
@@ -187,68 +252,124 @@ OnClickListener radio_listener = new OnClickListener() {
}
};
</pre>
-<p>Our <code>onClick()</code> method will be handed the View clicked, so the first thing to do
-is cast it into a RadioButton. Then we pop up a
-{@link android.widget.Toast} message that displays the selection.</p>
-<li>Now, at the bottom of the <code>onCreate()</code> method, add the following:
+<p>First, the {@link android.view.View} that is passed to the {@link
+android.view.View.OnClickListener#onClick(View)} method is cast into a RadioButton. Then a
+{@link android.widget.Toast} message displays the selected radio button's text.</p>
+<li>Now, at the bottom of the {@link android.app.Activity#onCreate(Bundle) onCreate()} method, add
+the following:
<pre>
final RadioButton radio_red = (RadioButton) findViewById(R.id.radio_red);
final RadioButton radio_blue = (RadioButton) findViewById(R.id.radio_blue);
radio_red.setOnClickListener(radio_listener);
radio_blue.setOnClickListener(radio_listener);
</pre>
-<p>This captures each of the RadioButtons from our layout and adds the newly-created
-OnClickListener to each.</p>
-<li>Run it.</li>
+<p>This captures each of the {@link android.widget.RadioButton}s from the layout and adds the
+newly-created {@link android.view.View.OnClickListener} to each.</p>
+<li>Run the application.</li>
</ol>
-<p class="note"><strong>Tip:</strong> If you find that you need to change the state of a
-RadioButton in another way (such as when loading a saved {@link android.preference.CheckBoxPreference}),
-use <code>setChecked(true)</code> or <code>toggle()</code>.</p>
+
+<p class="note"><strong>Tip:</strong> If you need to change the state
+yourself (such as when loading a saved {@link android.preference.CheckBoxPreference}),
+use the {@link android.widget.CompoundButton#setChecked(boolean)} or {@link
+android.widget.CompoundButton#toggle()} method.</p>
<h2>ToggleButton</h2>
-<p>A button used specifically for toggling something on and off.</p>
+
+<p>In this section, you'll create a button used specifically for toggling between two
+states, using the {@link android.widget.ToggleButton} widget. This widget is an excellent
+alternative to radio buttons if you have two simple states that are mutually exclusive ("on" and
+"off", for example).</p>
<ol>
- <li>Open the layout file and, inside the LinearLayout, add the {@link android.widget.ToggleButton} element:
+ <li>Open the <code>res/layout/main.xml</code> file and add the {@link android.widget.ToggleButton}
+element (inside the {@link android.widget.LinearLayout}):
<pre>
-&lt;ToggleButton android:id="@+id/togglebutton"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
+ &lt;ToggleButton android:id="@+id/togglebutton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textOn="Vibrate on"
+ android:textOff="Vibrate off"/>
</pre>
+ <p>The attributes <code>android:textOn</code> and <code>android:textOff</code> specify the text
+for the button when the button has been toggled on or off. The default values are "ON" and
+"OFF".</p>
</li>
<li>To do something when the state is changed, add the following code
-to the end of the <code>onCreate()</code> method:
+to the end of the {@link android.app.Activity#onCreate(Bundle) onCreate()} method:
<pre>
final ToggleButton togglebutton = (ToggleButton) findViewById(R.id.togglebutton);
togglebutton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// Perform action on clicks
if (togglebutton.isChecked()) {
- Toast.makeText(HelloFormStuff.this, "ON", Toast.LENGTH_SHORT).show();
+ Toast.makeText(HelloFormStuff.this, "Checked", Toast.LENGTH_SHORT).show();
} else {
- Toast.makeText(HelloFormStuff.this, "OFF", Toast.LENGTH_SHORT).show();
+ Toast.makeText(HelloFormStuff.this, "Not checked", Toast.LENGTH_SHORT).show();
}
}
});
</pre>
-<p>This captures our ToggleButton element from the layout, then adds an on-click listener to it.
-The {@link android.view.View.OnClickListener} must define the <code>onClick()</code> method, which
-defines the action to be made when the button is clicked. Here, we query the current state of the
-ToggleButton, then pop up a {@link android.widget.Toast} message that displays the current state.
-Notice that the ToggleButton handles its own state change between checked and un-checked, so we just
-ask which it is.</p>
-<li>Run it.</li>
+<p>This captures the {@link android.widget.ToggleButton} element from the layout, then adds an
+{@link android.view.View.OnClickListener}. The {@link android.view.View.OnClickListener} must
+implement the {@link android.view.View.OnClickListener#onClick(View)} callback method, which
+defines the action to perform when the button is clicked. In this example, the callback
+method checks the new state of the button, then shows a {@link android.widget.Toast} message that
+indicates the current state.</p>
+
+<p>Notice that the {@link android.widget.ToggleButton} handles its own state change between checked
+and unchecked, so you just ask which it is.</p>
+<li>Run the application.</li>
</ol>
-<p class="note"><strong>Tip:</strong> By default, the text on the button is "ON" and "OFF", but
-you can change each of these with <code>setTextOn(<var>CharSequence</var>)</code> and
-<code>setTextOff(<var>CharSequence</var>)</code>. And, if you find that you need to change the state
-in another way (such as when loading a saved {@link android.preference.CheckBoxPreference}),
-use <code>setChecked(true)</code> or <code>toggle()</code>. </p>
+<p class="note"><strong>Tip:</strong> If you need to change the state
+yourself (such as when loading a saved {@link android.preference.CheckBoxPreference}),
+use the {@link android.widget.CompoundButton#setChecked(boolean)} or {@link
+android.widget.CompoundButton#toggle()} method.</p>
+
+
+
+
+<h2>RatingBar</h2>
+
+<p>In this section, you'll create a widget that allows the user to provide a rating,
+with the {@link android.widget.RatingBar} widget.</p>
+<ol>
+ <li>Open the <code>res/layout/main.xml</code> file and add the {@link android.widget.RatingBar}
+element (inside the {@link android.widget.LinearLayout}):
+<pre>
+ &lt;RatingBar android:id="@+id/ratingbar"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:numStars="5"
+ android:stepSize="1.0"/>
+</pre>
+ <p>The <code>android:numStars</code> attribute defines how many stars to display for the rating
+bar. The <code>android:stepSize</code> attribute defines the granularity for each
+star (for example, a value of <code>0.5</code> would allow half-star ratings). </p>
+</li>
+<li>To do something when a new rating has been set, add the following code
+to the end of the {@link android.app.Activity#onCreate(Bundle) onCreate()} method:
+<pre>
+final RatingBar ratingbar = (RatingBar) findViewById(R.id.ratingbar);
+ratingbar.setOnRatingBarChangeListener(new OnRatingBarChangeListener() {
+ public void onRatingChanged(RatingBar ratingBar, float rating, boolean fromUser) {
+ Toast.makeText(HelloFormStuff.this, "New Rating: " + rating, Toast.LENGTH_SHORT).show();
+ }
+});
+</pre>
+<p>This captures the {@link android.widget.RatingBar} widget from the layout with {@link
+android.app.Activity#findViewById(int)} and then sets an {@link
+android.widget.RatingBar.OnRatingBarChangeListener}. The {@link
+android.widget.RatingBar.OnRatingBarChangeListener#onRatingChanged(RatingBar,float,boolean)
+onRatingChanged()} callback method then defines the action to perform when the user sets a rating.
+In this case, a simple {@link android.widget.Toast} message displays the new rating.</p>
+
+<li>Run the application.</li>
+</ol>
-<p>If you've added all the form items above, your application should look something like this:</p>
+<p>If you've added all the form widgets above, your application should look like this:</p>
<img src="images/hello-formstuff.png" width="150px" />
<h3>References</h3>
@@ -258,5 +379,6 @@ use <code>setChecked(true)</code> or <code>toggle()</code>. </p>
<li>{@link android.widget.CheckBox}</li>
<li>{@link android.widget.RadioButton}</li>
<li>{@link android.widget.ToggleButton}</li>
+ <li>{@link android.widget.RatingBar}</li>
</ul>
diff --git a/docs/html/resources/tutorials/views/hello-gallery.jd b/docs/html/resources/tutorials/views/hello-gallery.jd
index 084f912..12d5a91 100644
--- a/docs/html/resources/tutorials/views/hello-gallery.jd
+++ b/docs/html/resources/tutorials/views/hello-gallery.jd
@@ -1,16 +1,21 @@
-page.title=Hello, Gallery
+page.title=Gallery
parent.title=Hello, Views
parent.link=index.html
@jd:body
-<p>A {@link android.widget.Gallery} is a View commonly used to display items in a horizontally scrolling list
-that locks the current selection at the center. When one is selected, we'll show a message.</p>
+<p>{@link android.widget.Gallery} is a layout widget used to display items in a
+horizontally scrolling list and positions the current selection at the center of the view.</p>
+
+<p>In this tutorial, you'll create a gallery of photos and then display a toast message each time a
+gallery item is selected.</p>
<ol>
- <li>Start a new project/Activity called HelloGallery.</li>
- <li>Add some images to your res/drawable/ directory.</li>
- <li>Open the layout file and make it like so:
+ <li>Start a new project named <em>HelloGallery</em>.</li>
+ <li>Find some photos you'd like to use, or use these <a
+href="{@docRoot}shareables/sample_images.zip">sample images</a>. Save the images into the project's
+<code>res/drawable/</code> directory.</li>
+ <li>Open the <code>res/layout/main.xml</code> file and insert the following:
<pre>
&lt;?xml version="1.0" encoding="utf-8"?>
&lt;Gallery xmlns:android="http://schemas.android.com/apk/res/android"
@@ -19,10 +24,10 @@ that locks the current selection at the center. When one is selected, we'll show
android:layout_height="wrap_content"
/>
</pre>
-</li>
-
+ </li>
-<li>Open the HelloGallery.java file. Insert the following for the <code>onCreate()</code> method:
+<li>Open the <code>HelloGallery.java</code> file and insert the following code for the
+{@link android.app.Activity#onCreate(Bundle) onCreate()} method:
<pre>
&#64;Override
public void onCreate(Bundle savedInstanceState) {
@@ -39,19 +44,46 @@ public void onCreate(Bundle savedInstanceState) {
});
}
</pre>
- <p>We start as usual: set the layout and capture the View we want (our Gallery).
-We then set an Adapter, called ImageAdapter for the Gallery&mdash;this is a new class that
-we'll create next. Then we create an item click listener for the Gallery. This is like a normal
-on-click listener (which you might be familiar with for buttons), but it listens to each item
-that we've added to the Gallery. The <code>onItemClick()</code> callback method
-receives the AdapterView where the click occurred, the specific View that received the click, the
-position of the View clicked (zero-based), and the row id of the item clicked (if applicable). All
-that we care about is the position, so that we can pop up a {@link android.widget.Toast} message that
-tells us the index position of the item clicked. We do this with <code>Toast.makeText().show()</code>.
+ <p>This starts by setting the {@code main.xml} layout as the content view and then capturing the
+{@link android.widget.Gallery} from
+the layout with {@link
+android.app.Activity#findViewById(int)}. A custom {@link android.widget.BaseAdapter} called
+<code>ImageAdapter</code> is
+instantiated and applied to the {@link android.widget.Gallery} with {@link
+android.widget.AdapterView#setAdapter(T) setAdapter()}. (The <code>ImageAdapter</code> class is
+defined next.)
+Then an anonymous {@link android.widget.AdapterView.OnItemClickListener} is instantiated. The
+{@link android.widget.AdapterView.OnItemClickListener#onItemClick(AdapterView,View,int,long)}
+callback method receives the {@link android.widget.AdapterView} where the click occurred, the
+specific {@link android.view.View} that received the click, the
+position of the {@link android.view.View} clicked (zero-based), and the row ID of the item clicked
+(if applicable). In this example, all that's needed is the position of the click to show a {@link
+android.widget.Toast} message that says the position of the item, using
+{@link android.widget.Toast#makeText(Context,CharSequence,int)} and {@link
+android.widget.Toast#show()} (in a real world scenario, this ID could be used to get the full sized
+image for some other task).
</p>
</li>
-
-<li>After the <code>onCreate()</code> method, add the <code>ImageAdapter</code> class:
+ <li>Create a new XML file in the <code>res/values/</code> directory named <code>attrs.xml</code>.
+Insert the following:
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;resources>
+ &lt;declare-styleable name="HelloGallery">
+ &lt;attr name="android:galleryItemBackground" />
+ &lt;/declare-styleable>
+&lt;/resources>
+</pre>
+ <p>This is a custom styleable resource that can be applied to a layout. In this case, it will be
+applied to the individual items placed into the {@link android.widget.Gallery} widget. The
+<code>&lt;attr></code> element defines a specific attribute for the styleable, and in this case, it
+refers to an existing platform attribute, {@link android.R.attr#galleryItemBackground}, which
+defines a border styling for gallery items. In the next step, you'll
+see how this attribute is referenced and then later applied to each item in the gallery.</p>
+ </li>
+
+ <li>Go back to the <code>HelloGallery.java</code> file. After the {@link
+ android.app.Activity#onCreate(Bundle)} method, define the custom <code>ImageAdapter</code> class:
<pre>
public class ImageAdapter extends BaseAdapter {
int mGalleryItemBackground;
@@ -100,26 +132,30 @@ public class ImageAdapter extends BaseAdapter {
}
</pre>
<p>First, there are a few member variables, including an array of IDs that reference
-the images we placed in our drawable resources directory.</p>
-<p>Next is the constructor, where we define the member Context. The rest of the constructor
-sets up a reference for our Gallery them, which adds the nice framing for each Gallery item.
-Once we have our <code>mGalleryItemBackground</code>, it's important to recycle the
-StyledAttribute for later re-use.</p>
-<p>The next three methods are required for basic member queries.
-But then we have the <code>getView()</code> method, which is called
-for each item read by our ImageAdapter, when the Gallery is being built. Here, we
-use our member Context to create a new {@link android.widget.ImageView}. We then define
-the image resource with the current position of the Gallery items (corresponding to our
-array of drawables), set the dimensions for the ImageView,
-set the image scaling to fit the ImageView dimensions, then finally set the
-background theme for the ImageView.</p>
-
-<p>See {@link android.widget.ImageView.ScaleType}
-for other image scaling options, in case you want to avoid stretching images that don't
-exactly match the ImageView dimensions.</p>
-
-<li>Now run it.</li>
+the images saved in the drawable resources directory ({@code res/drawable/}).</p>
+<p>Next is the class constructor, where the {@link android.content.Context} for an {@code
+ImageAdapter} instance is defined and the styleable
+resource defined in the last step is acquired and saved to a local field. At the end of the
+constructor, {@link android.content.res.TypedArray#recycle()} is called on the {@link
+android.content.res.TypedArray} so it can be re-used by the system.</p>
+<p>The methods {@link android.widget.Adapter#getCount()}, {@link
+android.widget.Adapter#getItem(int)}, and {@link android.widget.Adapter#getItemId(int)} are methods
+that must be implemented for simple queries on the {@link android.widget.Adapter}.
+The {@link android.widget.Adapter#getView(int,View,ViewGroup) method does the
+work to apply an image to an {@link android.widget.ImageView} that will be embedded in the
+{@link android.widget.Gallery}. In this method, the member {@link android.content.Context} is used
+to create a new {@link android.widget.ImageView}. The {@link android.widget.ImageView} is prepared
+by applying an image from the local array of drawable resources, setting the {@link
+android.widget.Gallery.LayoutParams} height and width for the image, setting the scale to fit the
+{@link android.widget.ImageView} dimensions, and then finally setting the background to use the
+styleable attribute acquired in the constructor.</p>
+
+<p>See {@link android.widget.ImageView.ScaleType} for other image scaling options.</p>
+</li>
+
+<li>Run the application.</li>
</ol>
+
<p>You should see something like this:</p>
<img src="images/hello-gallery.png" width="150px" />
@@ -129,7 +165,7 @@ exactly match the ImageView dimensions.</p>
<li>{@link android.widget.BaseAdapter}</li>
<li>{@link android.widget.Gallery}</li>
<li>{@link android.widget.ImageView}</li>
- <li>{@link android.widget.Toast}</li>
+ <li>{@link android.widget.AdapterView.OnItemClickListener}</li>
</ul>
diff --git a/docs/html/resources/tutorials/views/hello-gridview.jd b/docs/html/resources/tutorials/views/hello-gridview.jd
index ffb6c93..03bfc54 100644
--- a/docs/html/resources/tutorials/views/hello-gridview.jd
+++ b/docs/html/resources/tutorials/views/hello-gridview.jd
@@ -1,33 +1,44 @@
-page.title=Hello, GridView
+page.title=Grid View
parent.title=Hello, Views
parent.link=index.html
@jd:body
-<p>A {@link android.widget.GridView} displays items in a two-dimensional, scrolling grid. The items
-are acquired from a {@link android.widget.ListAdapter}.</p>
+<p>{@link android.widget.GridView} is a {@link android.view.ViewGroup} that displays items in a
+two-dimensional,
+scrollable grid. The grid items are automatically inserted to the layout using a {@link
+android.widget.ListAdapter}.</p>
+
+<p>In this tutorial, you'll create a grid of image thumbnails. When an item is selected, a
+toast message will display the position of the image.</p>
<ol>
- <li>Start a new project/Activity called HelloGridView.</li>
- <li>Find some photos you'd like to use, or copy some from the SDK samples res/drawable/
- folder of your project.</li>
- <li>Open the layout and make it like so:
+ <li>Start a new project named <em>HelloGridView</em>.</li>
+ <li>Find some photos you'd like to use, or <a
+href="{@docRoot}shareables/sample_images.zip">download these sample images</a>. Save the image files
+into the project's
+<code>res/drawable/</code> directory.</li>
+ <li>Open the <code>res/layout/main.xml</code> file and insert the following:
<pre>
&lt;?xml version="1.0" encoding="utf-8"?>
&lt;GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/gridview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
+ android:columnWidth="90dp"
android:numColumns="auto_fit"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
- android:columnWidth="90dp"
android:stretchMode="columnWidth"
android:gravity="center"
/>
</pre>
+ <p>This {@link android.widget.GridView} will fill the entire screen. The attributes are rather
+self explanatory. For more information about valid attributes, see the {@link
+android.widget.GridView} reference.</p>
</li>
- <li>Open the HelloGridView Java file. Insert the following for the <code>onCreate()</code> method:
+ <li>Open <code>HelloGridView.java</code> and insert the following code for the
+{@link android.app.Activity#onCreate(Bundle) onCreate()} method:
<pre>
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -35,12 +46,33 @@ public void onCreate(Bundle savedInstanceState) {
GridView gridview = (GridView) findViewById(R.id.gridview);
gridview.setAdapter(new ImageAdapter(this));
+
+ gridview.setOnItemClickListener(new OnItemClickListener() {
+ public void onItemClick(AdapterView&lt;?> parent, View v, int position, long id) {
+ Toast.makeText(HelloGridView.this, "" + position, Toast.LENGTH_SHORT).show();
+ }
+ });
}
</pre>
- <p>Here, we get a handle on our GridView, from the layout, and give it an Adapter.
- We're actually going to create our own Adapter called ImageAdapter.</p>
+ <p>After the {@code main.xml} layout is set for the content view, the
+{@link android.widget.GridView} is captured from the layout with {@link
+android.app.Activity#findViewById(int)}. The {@link
+android.widget.GridView#setAdapter(T) setAdapter()} method then sets a custom adapter ({@code
+ImageAdapter}) as the source for all items to be displayed in the grid. The {@code ImageAdapter} is
+created in the next step.</p>
+<p>To do something when an item in the grid is clicked, the {@link
+android.widget.AdapterView#setOnItemClickListener(OnItemClickListener) setOnItemClickListener()}
+method is passed a new {@link android.widget.AdapterView.OnItemClickListener}. This anonymous
+instance defines the {@link
+android.widget.AdapterView.OnItemClickListener#onItemClick(AdapterView,View,int,long)
+onItemClick()} callback method to show a {@link android.widget.Toast} that displays the index
+position (zero-based) of the selected item (in a real world scenario, the position could be used to
+get the full sized
+image for some other task).</p>
+
</li>
-<li>Create a new class (nested or otherwise), called ImageAdapter, which extends {@link android.widget.BaseAdapter}:
+<li>Create a new class called <code>ImageAdapter</code> that extends {@link
+android.widget.BaseAdapter}:
<pre>
public class ImageAdapter extends BaseAdapter {
private Context mContext;
@@ -93,37 +125,58 @@ public class ImageAdapter extends BaseAdapter {
};
}
</pre>
- <p>First we take care of some required methods inherited from BaseAdapter.
- The constructor and <code>getCount()</code> are self-explanitory. Normally, <code>getItem()</code>
- should return the actual object at the specified position in our Adapter, but for this Hello World,
- we're not going to bother. Likewise, <code>getItemId()</code> should return the row id of
- the item, but right now we don't care.</p>
- <p>However, <code>getView()</code> is the method we care about. This one creates a new View for each image that we
- put in our ImageAdapter. So we're going to create an ImageView each time. When this is called, we're
- going to receive a View, which is likely a recycled View object (at least after the first call), so we
- check for this&mdash;if it's null, we initialize the ImageView and setup all the properties we want.
- The <code>LayoutParams()</code> initialization sets the height and width of the View&mdash;this ensures
- that no matter the drawable size, each image is resized and cropped to fit in the ImageView (if necessary).
- With <code>setScaleType()</code>, we say that images should be cropped toward the center (if necessary).
- And finally, we set the padding within the ImageView. (Note that, if the images have various aspect-ratios,
- as they do in this demo, then less padding will cause for more cropping of the image, if it does not match
- the dimensions given to the ImageView.) At the end of <code>getView()</code> we set the image resource and
- return the ImageView.</p>
- <p>All that's left is our array or drawable resources at the bottom.</p>
+<p>First, this implements some required methods inherited from {@link
+android.widget.BaseAdapter}. The constructor and {@link
+android.widget.Adapter#getCount()} are self-explanatory. Normally, {@link
+android.widget.Adapter#getItem(int)} should return the actual object at the specified position in
+the adapter, but it's ignored for this example. Likewise, {@link
+android.widget.Adapter#getItemId(int)} should return the row id of the item, but it's not
+needed here.</p>
+
+<p>The first method necessary is {@link android.widget.Adapter#getView(int,View,ViewGroup)
+getView()}. This method creates a new {@link android.view.View} for each image added to the {@code
+ImageAdapter}. When this is called, a {@link android.view.View} is passed in, which is normally a
+recycled object (at least after this has been called once), so there's a check to see if the
+object is null. If it <em>is</em> null, an {@link android.widget.ImageView} is instantiated and
+configured with desired properties for the image presentation:</p>
+<ul>
+ <li>{@link android.view.View#setLayoutParams(ViewGroup.LayoutParams)} sets
+the height and width for the View&mdash;this ensures that, no matter the size of the drawable, each
+image is resized and cropped to fit in these dimensions, as appropriate.</li>
+ <li>{@link android.widget.ImageView#setScaleType(ImageView.ScaleType)} declares that images should
+be cropped toward the center (if necessary).</li>
+ <li>{@link android.widget.ImageView#setPadding(int,int,int,int)} defines the padding for all
+sides. (Note that, if the images have different aspect-ratios, then less
+padding will cause for more cropping of the image if it does not match
+the dimensions given to the ImageView.)</li>
+</ul>
+
+<p>If the {@link android.view.View} passed to {@link
+android.widget.Adapter#getView(int,View,ViewGroup) getView()} is <em>not</em> null, then the local
+{@link android.widget.ImageView} is initialized with the recycled {@link android.view.View}
+object.</p>
+
+<p>At the end of the {@link android.widget.Adapter#getView(int,View,ViewGroup) getView()} method,
+the {@code
+position} integer passed into the method is used to select an image from the {@code mThumbIds}
+array, which is set as the image resource for the {@link android.widget.ImageView}.</p>
+<p>All that's left is to define the {@code mThumbIds} array of drawable resources.</p>
</li>
-<li>Run it.</li>
+<li>Run the application.</li>
</ol>
<p>Your grid layout should look something like this:</p>
<img src="images/hello-gridview.png" width="150px" />
-<p>Try experimenting with the behaviors of the GridView and ImageView by adjusting their properties. For example,
- instead of setting the ImageView LayoutParams, you can try using
- {@link android.widget.ImageView#setAdjustViewBounds(boolean)}. </p>
+<p>Try experimenting with the behaviors of the {@link android.widget.GridView} and {@link
+android.widget.ImageView} elements by adjusting their properties. For example, instead of using
+{@link android.view.View#setLayoutParams(ViewGroup.LayoutParams)}, try using
+{@link android.widget.ImageView#setAdjustViewBounds(boolean)}. </p>
<h3>References</h3>
<ul>
<li>{@link android.widget.GridView}</li>
<li>{@link android.widget.ImageView}</li>
<li>{@link android.widget.BaseAdapter}</li>
+ <li>{@link android.widget.AdapterView.OnItemClickListener}</li>
</ul>
diff --git a/docs/html/resources/tutorials/views/hello-linearlayout.jd b/docs/html/resources/tutorials/views/hello-linearlayout.jd
index 0e8947c..8e072b1 100644
--- a/docs/html/resources/tutorials/views/hello-linearlayout.jd
+++ b/docs/html/resources/tutorials/views/hello-linearlayout.jd
@@ -1,16 +1,18 @@
-page.title=Hello, LinearLayout
+page.title=Linear Layout
parent.title=Hello, Views
parent.link=index.html
@jd:body
-<p>A {@link android.widget.LinearLayout} is a GroupView that will lay child View elements
-vertically or horizontally.</p>
+<p>{@link android.widget.LinearLayout} is a {@link android.view.ViewGroup} that displays child
+{@link android.view.View} elements in a linear direction, either vertically or horizontally.</p>
+<p>You should be careful about over-using the {@link android.widget.LinearLayout}. If you begin
+nesting multiple {@link android.widget.LinearLayout}s, you may want to consider using a {@link
+android.widget.RelativeLayout} instead.</p>
<ol>
- <li>Start a new project/Activity called HelloLinearLayout.</li>
- <li>Open the layout file.
- Make it like so:
+ <li>Start a new project named <em>HelloLinearLayout</em>.</li>
+ <li>Open the <code>res/layout/main.xml</code> file and insert the following:
<pre>
&lt;?xml version="1.0" encoding="utf-8"?>
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
@@ -18,113 +20,114 @@ vertically or horizontally.</p>
android:layout_width="fill_parent"
android:layout_height="fill_parent">
- &lt;LinearLayout
- android:orientation="horizontal"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:layout_weight="1">
+ &lt;LinearLayout
+ android:orientation="horizontal"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:layout_weight="1">
+ &lt;TextView
+ android:text="red"
+ android:gravity="center_horizontal"
+ android:background="#aa0000"
+ android:layout_width="wrap_content"
+ android:layout_height="fill_parent"
+ android:layout_weight="1"/>
+ &lt;TextView
+ android:text="green"
+ android:gravity="center_horizontal"
+ android:background="#00aa00"
+ android:layout_width="wrap_content"
+ android:layout_height="fill_parent"
+ android:layout_weight="1"/>
+ &lt;TextView
+ android:text="blue"
+ android:gravity="center_horizontal"
+ android:background="#0000aa"
+ android:layout_width="wrap_content"
+ android:layout_height="fill_parent"
+ android:layout_weight="1"/>
+ &lt;TextView
+ android:text="yellow"
+ android:gravity="center_horizontal"
+ android:background="#aaaa00"
+ android:layout_width="wrap_content"
+ android:layout_height="fill_parent"
+ android:layout_weight="1"/>
+ &lt;/LinearLayout>
- &lt;TextView
- android:text="red"
- android:gravity="center_horizontal"
- android:background="#aa0000"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:layout_weight="1"/>
-
- &lt;TextView
- android:text="green"
- android:gravity="center_horizontal"
- android:background="#00aa00"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:layout_weight="1"/>
-
- &lt;TextView
- android:text="blue"
- android:gravity="center_horizontal"
- android:background="#0000aa"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:layout_weight="1"/>
-
- &lt;TextView
- android:text="yellow"
- android:gravity="center_horizontal"
- android:background="#aaaa00"
- android:layout_width="wrap_content"
- android:layout_height="fill_parent"
- android:layout_weight="1"/>
-
- &lt;/LinearLayout>
-
- &lt;LinearLayout
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:layout_weight="1">
-
- &lt;TextView
- android:text="row one"
- android:textSize="15pt"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1"/>
-
- &lt;TextView
- android:text="row two"
- android:textSize="15pt"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1"/>
-
- &lt;TextView
- android:text="row three"
- android:textSize="15pt"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1"/>
-
- &lt;TextView
- android:text="row four"
- android:textSize="15pt"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:layout_weight="1"/>
-
- &lt;/LinearLayout>
-
+ &lt;LinearLayout
+ android:orientation="vertical"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:layout_weight="1">
+ &lt;TextView
+ android:text="row one"
+ android:textSize="15pt"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"/>
+ &lt;TextView
+ android:text="row two"
+ android:textSize="15pt"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"/>
+ &lt;TextView
+ android:text="row three"
+ android:textSize="15pt"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"/>
+ &lt;TextView
+ android:text="row four"
+ android:textSize="15pt"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"/>
+ &lt;/LinearLayout>
+
&lt;/LinearLayout>
</pre>
- <p>Carefully inspect the XML. You'll notice how this layout works a lot like
- an HTML layout. There is one parent LinearLayout that is defined to lay
- its child elements vertically. The first child is another LinearLayout that uses a horizontal layout
- and the second uses a vertical layout. Each LinearLayout contains several {@link android.widget.TextView}
- elements.</p>
+
+<p>Carefully inspect this XML. There is a root {@link android.widget.LinearLayout} that defines
+its orientation to be vertical&mdash;all child {@link android.view.View}s (of which it has two) will
+be stacked vertically. The first child is
+another {@link android.widget.LinearLayout} that uses a horizontal orientation and the second child
+is a {@link android.widget.LinearLayout} that uses a vertical orientation. Each of these nested
+{@link android.widget.LinearLayout}s contain several {@link android.widget.TextView} elements, which
+are oriented with each other in the manner defined by their parent {@link
+android.widget.LinearLayout}.</p>
</li>
-<li>Now open the HelloLinearLayout Activity and be sure it loads this layout in the <code>onCreate()</code> method:</p>
+<li>Now open <code>HelloLinearLayout.java</code> and be sure it loads the
+<code>res/layout/main.xml</code> layout in the
+{@link android.app.Activity#onCreate(Bundle) onCreate()} method:</p>
<pre>
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
</pre>
-<p><code>R.layout.main</code> refers to the <code>main.xml</code> layout file.</p>
+<p>The {@link android.app.Activity#setContentView(int)} method loads the
+layout file for the {@link android.app.Activity}, specified by the resource
+ID &mdash; <code>R.layout.main</code> refers to the <code>res/layout/main.xml</code> layout
+file.</p>
</li>
-<li>Run it.</li>
+<li>Run the application.</li>
</ol>
<p>You should see the following:</p>
<img src="images/hello-linearlayout.png" width="150px" />
-<p>Notice how the various XML attributes define the View's behavior.
-Pay attention to the effect of the <code>layout_weight</code>. Try
- experimenting with different values to see how the screen real estate is
- distributed based on the weight of each element.</p>
+<p>Notice how the XML attributes define each View's behavior. Try
+experimenting with different values for <code>android:layout_weight</code> to see how the screen
+real estate is distributed based on the weight of each element. See the <a
+href="{@docRoot}guide/topics/ui/layout-objects.html#linearlayout">Common Layout Objects</a>
+document for more about how {@link android.widget.LinearLayout} handles the
+<code>android:layout_weight</code> attribute.</p>
<h3>References</h3>
<ul>
<li>{@link android.widget.LinearLayout}</li>
-<li>{@link android.widget.TextView}</li>
+ <li>{@link android.widget.TextView}</li>
</ul>
diff --git a/docs/html/resources/tutorials/views/hello-listview.jd b/docs/html/resources/tutorials/views/hello-listview.jd
index d90005b..194258e 100644
--- a/docs/html/resources/tutorials/views/hello-listview.jd
+++ b/docs/html/resources/tutorials/views/hello-listview.jd
@@ -1,36 +1,88 @@
-page.title=Hello, ListView
+page.title=List View
parent.title=Hello, Views
parent.link=index.html
@jd:body
-<p>A {@link android.widget.ListView} is a View that shows items in a vertically scrolling list. The items are
- acquired from a {@link android.widget.ListAdapter}.</p>
+<p>{@link android.widget.ListView} is a {@link android.view.ViewGroup} that creates a list of
+scrollable items. The list items are automatically inserted to the list using a {@link
+android.widget.ListAdapter}.</p>
+<p>In this tutorial, you'll create a scrollable list of country names that are read from a string array.
+When a list item is selected, a toast message will display the position of the item in the list.</p>
<ol>
- <li>Start a new project/ListActivity called HelloListView.</li>
- <li>Open the HelloListView Java file. Make the class extend ListActivity (instead of Activity).
+ <li>Start a new project named <em>HelloListView</em>.</li>
+ <li>Create an XML file named <code>list_item.xml</code> and save it inside the
+<code>res/layout/</code> folder. Insert the following:
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:padding="10dp"
+ android:textSize="16sp" >
+&lt;/TextView>
+</pre>
+ <p>This file defines the layout for each item that will be placed in the {@link
+android.widget.ListView}.</p>
+ </li>
+
+ <li>Open the <code>HelloListView.java</code> and make the class extend {@link
+android.app.ListActivity} (instead of {@link android.app.Activity}):
<pre>public class HelloListView extends ListActivity {</pre>
</li>
- <li>Insert the following for the <code>onCreate()</code> method:
+ <li>Insert the following code for the {@link android.app.Activity#onCreate(Bundle) onCreate()}
+method:
<pre>
&#64;Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
-
- setListAdapter(new ArrayAdapter&lt;String>(this,
- android.R.layout.simple_list_item_1, COUNTRIES));
- getListView().setTextFilterEnabled(true);
+
+ setListAdapter(new ArrayAdapter&lt;String>(this, R.layout.list_item, COUNTRIES));
+
+ ListView lv = getListView();
+ lv.setTextFilterEnabled(true);
+
+ lv.setOnItemClickListener(new OnItemClickListener() {
+ public void onItemClick(AdapterView&lt;?> parent, View view,
+ int position, long id) {
+ // When clicked, show a toast with the TextView text
+ Toast.makeText(getApplicationContext(), ((TextView) view).getText(),
+ Toast.LENGTH_SHORT).show();
+ }
+ });
}
</pre>
- <p>Notice that we don't need to load a layout (at least, not in this case, because we're using
- the whole screen for our list). Instead, we just call <code>setListAdapter()</code> (which automatically
- adds a ListView to the ListActivity), and provide it with an ArrayAdapter that binds a
- <code>simple_list_item_1</code> layout item to each entry in the <code>COUNTRIES</code>
- array (added next). The next line of code adds a text filter to the ListView, so that when the user
- begins typing, the list will filter the entire view to display only the items that match the entry.</p>
- </li>
- <li>Following the <code>onCreate()</code> method, add the String array:
+<p>Notice that this does not load a layout file for the Activity (which you usually do with {@link
+android.app.Activity#setContentView(int)}). Instead, {@link
+android.app.ListActivity#setListAdapter(ListAdapter)} automatically
+adds a {@link android.widget.ListView} to fill the entire screen of the {@link
+android.app.ListActivity}. This method takes an {@link android.widget.ArrayAdapter}, which
+manages the array of list items that will be placed into the {@link android.widget.ListView}. The
+{@link android.widget.ArrayAdapter} constructor takes the application {@link
+android.content.Context}, the
+layout description for each list item (created in
+the previous step), and a {@link java.util.List} of objects to insert in the {@link
+android.widget.ListView} (defined next).</p>
+
+<p>The {@link android.widget.ListView#setTextFilterEnabled(boolean)} method turns on text filtering
+for the {@link android.widget.ListView}, so that when the user begins typing, the list will be
+filtered.</p>
+
+<p>The {@link android.widget.ListView#setOnItemClickListener(OnItemClickListener)} method defines
+the on-click listener for each item. When an item in the {@link android.widget.ListView} is clicked,
+the {@link android.widget.AdapterView.OnItemClickListener#onItemClick(AdapterView,View,int,long)
+onItemClick()} method is called and a {@link android.widget.Toast} message is displayed, using the
+text from the clicked item.</p>
+
+<p class="note"><strong>Tip:</strong> You can use list item designs provided by the platform
+instead of defining your own layout file for the {@link android.widget.ListAdapter}. For example,
+try using <code>android.R.layout.simple_list_item_1</code> instead of
+<code>R.layout.list_item</code>.</p>
+</li>
+
+<li>After the {@link android.app.Activity#onCreate(Bundle) onCreate()} method, add the string
+array:
<pre>
static final String[] COUNTRIES = new String[] {
"Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra",
@@ -76,12 +128,40 @@ public void onCreate(Bundle savedInstanceState) {
"Yemen", "Yugoslavia", "Zambia", "Zimbabwe"
};
</pre>
+ <p>This is the array of strings that will be placed into the {@link android.widget.ListView}.</p>
</li>
-<li> Run it.</li>
+<li>Run the application.</li>
</ol>
-<p>You can scroll the list, or type to filter it. You should see something like this:</p>
+<p>You can scroll the list, or type to filter it, then click an item to see a message. You
+should see something like this:</p>
<img src="images/hello-listview.png" width="150px" />
+<p>Note that using a hard-coded string array is not the best design practice. One is
+used in this tutorial for simplicity, in order to demonstrate the {@link
+android.widget.ListView} widget. The better practice is to reference a string array
+defined by an external resource, such as with a {@code &lt;string-array&gt;}
+resource in your project {@code res/values/strings.xml} file. For example:</p>
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;resources>
+ &lt;string-array name="countries_array">
+ &lt;item>Bahrain&lt;/item>
+ &lt;item>Bangladesh&lt;/item>
+ &lt;item>Barbados&lt;/item>
+ &lt;item>Belarus&lt;/item>
+ &lt;item>Belgium&lt;/item>
+ &lt;item>Belize&lt;/item>
+ &lt;item>Benin&lt;/item>
+ &lt;/string-array>
+&lt;/resources>
+</pre>
+<p>To use these resource strings for the {@link android.widget.ArrayAdapter}, replace the original
+{@link android.app.ListActivity#setListAdapter(ListAdapter)} line with the following:</p>
+<pre>
+String[] countries = getResources().getStringArray(R.array.countries_array);
+setListAdapter(new ArrayAdapter&lt;String>(this, R.layout.list_item, countries));
+</pre>
+
<h3>References</h3>
<ul>
<li>{@link android.widget.ListView}</li>
diff --git a/docs/html/resources/tutorials/views/hello-mapview.jd b/docs/html/resources/tutorials/views/hello-mapview.jd
index 531300f..a3fa548 100644
--- a/docs/html/resources/tutorials/views/hello-mapview.jd
+++ b/docs/html/resources/tutorials/views/hello-mapview.jd
@@ -1,273 +1,303 @@
-page.title=Hello, MapView
+page.title=Google Map View
parent.title=Hello, Views
parent.link=index.html
@jd:body
+<p>Using the Google Maps library, you can create your own map-viewing Activity. In this
+tutorial, you'll create a simple map application in two parts. In Part 1, you'll create an app that
+shows a map the user can pan and zoom. In Part 2, you'll add overlay items that mark
+points of interest.</p>
+
<div class="special">
-<p>This tutorial requires that you have the Google Maps external library
-installed in your SDK environment. By default the Android SDK includes the
-Google APIs add-on, which in turn includes the Maps external library. If you
-don't have the Google APIs SDK add-on, you can download it from this
-location:</p>
-
-<p style="margin-left:2em;"><a
-href="http://code.google.com/android/add-ons/google-apis">http://code.google.com/android/add-ons/google-apis</a></p>
-
-<p>The Google APIs add-on requires Android 1.5 SDK or later release. After
-installing the add-on in your SDK, set your project properties to use the build
-target called "Google APIs Add-on". See the instructions for setting a build
+<p>This tutorial requires that you have the external Google Maps library
+installed in your SDK environment. The Maps library is included with the Google APIs
+add-on, which you can install using the Android SDK and
+AVD Manager. To learn how, see <a href="{@docRoot}sdk/adding-components.html">Adding SDK
+Components</a>.</p>
+
+<p>After installing the Google APIs add-on in your SDK, set your project properties to use the build
+target called "Google APIs by Google Inc.". See the instructions for setting a build
target in <a href="{@docRoot}guide/developing/eclipse-adt.html">Developing in
Eclipse with ADT</a> or <a
href="{@docRoot}guide/developing/other-ide.html">Developing in Other IDEs</a>,
as appropriate for your environment. </p>
-<p>You will also need to use the android tool to set up an AVD that uses the
-Google APIs deployment target. See <a
+<p>You will also need to set up a new AVD that uses the same Google APIs deployment target. See <a
href="{@docRoot}guide/developing/tools/avd.html">Android Virtual Devices</a> for
-more information. Once you have set up your environment, you will be able to
-build and run the project described in this tutorial</a></p>
+more information.</p>
+
+<p>For reference material, see the <a
+href="http://code.google.com/android/add-ons/google-apis/reference/index.html">Google Maps
+library documentation</a>.</p>
</div>
-<p>A MapView allows you to create your own map-viewing Activity.
-First, we'll create a simple Activity that can view and navigate a map. Then we will add some overlay items.</p>
+<h2>Part 1: Creating a Map Activity</h2>
<ol>
- <li>Start a new project/Activity called HelloMapView.
-
- <li>Because we're using the Google Maps library,
- which is not a part of the standard Android library, we need to
- declare it in the Android Manifest. Open the AndroidManifest.xml
- file and add the following as a child of the <code>&lt;application></code> element:
-
- <pre>&lt;uses-library android:name="com.google.android.maps" /></pre>
- </li>
- <li>We also need access to the internet in order to retrieve the Google Maps tiles,
- so the application must request the {@link android.Manifest.permission#INTERNET INTERNET} permissions.
- In the manifest file, add the following as a child of the <code>&lt;manifest></code> element:
- <pre>&lt;uses-permission android:name="android.permission.INTERNET" /></pre>
- </li>
- <li>Now open the main layout file for your project. Define a layout with a com.google.android.maps.MapView
- inside a android.widget.RelativeLayout:
+ <li>Start a new project named <em>HelloGoogleMaps</em>.</li>
+
+ <li>Because the Maps library is not a part of the standard Android library, you must
+ declare it in the Android Manifest. Open the <code>AndroidManifest.xml</code>
+ file and add the following as a child of the <code>&lt;application></code> element:
+ <pre>&lt;uses-library android:name="com.google.android.maps" /></pre>
+ </li>
+
+ <li>You also need access to the Internet in order to retrieve map tiles,
+ so you must also request the {@link android.Manifest.permission#INTERNET} permission.
+ In the manifest file, add the following as a child of the <code>&lt;manifest></code> element:
+ <pre>&lt;uses-permission android:name="android.permission.INTERNET" /></pre>
+ </li>
+
+ <li>While you're in the manifest, give the map some more space by getting rid of the title bar
+with the "NoTitleBar" theme:
+<pre>
+&lt;activity android:name=".HelloGoogleMaps" android:label="@string/app_name"
+ <strong>android:theme="@android:style/Theme.NoTitleBar"</strong>&gt;
+</pre>
+ </li>
+
+ <li>Open the <code>res/layout/main.xml</code> file and add a single
+ {@code com.google.android.maps.MapView} as the root node:
<pre>
&lt;?xml version="1.0" encoding="utf-8"?>
-&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/mainlayout"
- android:orientation="vertical"
+&lt;com.google.android.maps.MapView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/mapview"
android:layout_width="fill_parent"
- android:layout_height="fill_parent" >
-
- &lt;com.google.android.maps.MapView
- android:id="@+id/mapview"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:clickable="true"
- android:apiKey="<em>Your Maps API Key</em>"
- />
-
-&lt;/RelativeLayout>
+ android:layout_height="fill_parent"
+ android:clickable="true"
+ android:apiKey="<em>Your Maps API Key goes here</em>"
+/>
</pre>
- <p>The <code>clickable</code> attribute defines whether you want to allow user-interaction with the map.
- In this case, we set it "true" so that the user can navigate.</p>
-
- <p>The <code>apiKey</code> attribute holds the Google Maps API Key that proves your application and signer
- certificate has been registered with the Google Maps service. Because MapView uses Google Maps data, this key is required
- in order to receive the map data, even while you are developing. Registration is free and it only takes a couple
- minutes to register your certificate and receive a Maps API Key. For instructions on getting a key, read
- <a href="http://code.google.com/android/add-ons/google-apis/mapkey.html">Obtaining a Maps API Key</a>.
- (For the purpose of this tutorial, you should register with the fingerprint of the SDK debug certificate.)
- Once you've acquired the Maps API Key, insert it for the <code>apiKey</code> value.</p></li>
-
- <li>Now open the HelloMapView.java file. For this Activity, we're going to extend the special sub-class of
- Activity called MapActivity, so change the class declaration to extend
- MapActicity, instead of Activity:</p>
-
- <pre>public class HelloMapView extends MapActivity {</pre>
-
- <li>The <code>isRouteDisplayed()</code> method is required, so add it inside the class:
+ <p>The <code>android:clickable</code> attribute defines whether you want to allow
+ user-interaction with the map. If this is "false" then touching the map does nothing.</p>
+
+ <p>The <code>android:apiKey</code> attribute holds the Maps API Key for your
+ application, which proves your application and signer certificate has been registered with the
+ Maps service. This is required in order to receive the map data, even while you are
+ developing. Registration to the service is free and it only takes a couple
+ minutes to register your certificate and get a Maps API Key.</p>
+ <p>Go now to get a key. For instructions, read
+ <a href="http://code.google.com/android/add-ons/google-apis/mapkey.html">Obtaining a Maps API
+ Key</a>. For the purpose of this tutorial, you should <a
+ href="http://code.google.com/android/add-ons/google-apis/mapkey.html#getdebugfingerprint">register
+ with the SDK debug certificate</a>, which will only be valid while your application is signed
+ with the debug key (once you sign with your private key, you will need a new API key).
+ When you get your key, insert it for the value of <code>android:apiKey</code>.</p>
+ </li>
+
+ <li>Now open the <code>HelloGoogleMaps.java</code> file. For this Activity, extend
+ {@code MapActivity} (instead of {@code android.app.Activity}):</p>
+
+ <pre>public class HelloGoogleMaps extends MapActivity {</pre>
+ <p>This is a special sub-class of {@link android.app.Activity}, provided by the Maps
+ library, which provides important map capabilities.</p>
+
+ <li>Inside every {@code MapActivity}, the <code>isRouteDisplayed()</code> method is required, so
+ override this method:
<pre>
&#64;Override
protected boolean isRouteDisplayed() {
return false;
}
</pre>
-<p>You can actually run this now, but all it does is allow you to pan around the map.</p>
-<p>Android provides a handy {@link android.widget.ZoomControls} widget for zooming in and out of a View.
-MapView can automatically hook one for us by requesting it with the <code>getZoomControls()</code>
-method. Let's do this.</p>
+<p>This method is required for some accounting from the Maps service to see if you're currently
+displaying any route information. In this case, you're not, so return false.</p>
+</li>
-<li>Go back to the layout file. We need a new ViewGroup element, in which we'll
- place the ZoomControls. Just below the MapView element (but inside the RelativeLayout), add this element:
+<li>Now add the standard {@link android.app.Activity#onCreate(Bundle) onCreate()} callback method
+to the class:
<pre>
-&lt;LinearLayout
- android:id="@+id/zoomview"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignBottom="@id/mapview"
- android:layout_centerHorizontal="true"
-/></pre>
-
- <p>It doesn't really matter what kind of ViewGroup we use, because we just want a
- container that we can position within our root RelativeLayout.</p>
-
- <p>The last two attributes are available only to an element that's a child of a
- RelativeLayout. <code>layout_alignBottom</code> aligns the bottom of this element to the bottom of
- the element identified with a resource tag (which must be a sibling to this element).
- <code>layout_centerHorizontal</code> centers this on the horizontal plane.</p></li>
-
- <li>Now go back to the HelloMapView class. We'll now retrieve the ZoomControls object from
- the MapView and add it to our new layout element. First, at the top of the HelloMapView,
- instantiate handles for the MapView and LinearLayout, plus a ZoomControl object:
-<pre>
-LinearLayout linearLayout;
-MapView mapView;
-ZoomControls mZoom;</pre></li>
-
- <li>Then initialize each of these in <code>onCreate()</code>. We'll capture the LinearLayout and
- MapView through their layout resources. Then get the ZoomControls from the MapView::
+&#64;Override
+public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+}
+</pre>
+<p>This loads the layout file created above. In fact, this is now a workable application that will
+display map tiles and allow the user to pan around the map. But there's no ability to zoom.
+Fortunately, there's a very simple zoom feature built into the {@code MapView} class, which you can
+summon with {@code setBuiltInZoomControls(boolean)}. Do this at the end of the {@link
+android.app.Activity#onCreate(Bundle) onCreate()} method:</p>
<pre>
-linearLayout = (LinearLayout) findViewById(R.id.zoomview);
-mapView = (MapView) findViewById(R.id.mapview);
-mZoom = (ZoomControls) mapView.getZoomControls();</pre>
-
- <p>By using the ZoomControls object provided by MapView, we don't have to do any of the work
- required to actually perform the zoom operations. The ZoomControls widget that MapView
- returns for us is already hooked into the MapView and works as soon as we add it to the
- layout. The controls will appear whenever the user touches the map, then dissapear after
- a few moments of inactivity.</p></li>
-
- <li>Now just plug our ZoomControls into the LinearLayout we added:
-
- <pre>linearLayout.addView(mZoom);</pre></li>
-
- <li>Run it.</li>
+ MapView mapView = (MapView) findViewById(R.id.mapview);
+ mapView.setBuiltInZoomControls(true);
+</pre>
+</li>
+<li>That's all there is to it. Run the application. (Remember, you must have an <a
+href="{@docRoot}guide/developing/tools/avd.html">AVD</a> configured to use the Google APIs
+target, or be using a development device that includes the Maps library.)</li>
</ol>
-<hr/>
+<h2>Part 2: Adding Overlay Items</h2>
-<p>So, we now have full interaction controls. All well and good, but what we really want our map
-for is custom markers and layovers. Let's add some Overlay
-objects to our map. To do this, we're going to
-implement the ItemizedOverlay
-class, which can manage a whole set of Overlay items for us.</p>
+<p>So, now you have a map, but in many cases you'll also want to create your own map
+markers and lay-overs. That's what you'll do now. In order to do so, you must implement the
+{@code ItemizedOverlay} class, which can manage a whole set of {@code Overlay} (which are the
+individual items placed on the map).</p>
<ol>
- <li>Create a new Java class named HelloItemizedOverlay that implements ItemizedOverlay.
-
- <p>When using Eclipse, right-click the package name in the Eclipse Package Explorer, and select New > Class. Fill-in
- the Name field as <em>HelloItemizedOverlay</em>. For the Superclass, enter
- <em>com.google.android.maps.ItemizedOverlay</em>. Click the checkbox for <em>Constructors from
- superclass</em>. Click Finish.</p></li>
-
- <li> First thing, we need an OverlayItem ArrayList, in which we'll put each of the OverlayItem
- objects we want on our map. Add this at the top of the HelloItemizedOverlay class:
-
- <pre>private ArrayList&lt;OverlayItem> mOverlays = new ArrayList&lt;OverlayItem>();</pre></li>
-
- <li>All the constructor does is define the default marker to be used on each of the OverlayItems.
- In order for the Drawable to actually get drawn, it must have its bounds defined. And we want the
- center-point at the bottom of the image to be the point at which it's attached to the map
- coordinates. We handle all this with the boundCenterBottom() method. Wrap this around our
- defaultMarker, so the super constructor call looks like this:
-
- <pre>super(boundCenterBottom(defaultMarker));</pre></li>
-
- <li>In order to add new OverlayItems to our ArrayList, we need a new public method. We'll handle
- this with the following method:
+ <li>Create a new Java class named <code>HelloItemizedOverlay</code> that implements
+ {@code ItemizedOverlay}.
+
+ <p>When using Eclipse, right-click the package name in the Eclipse Package Explorer, and
+ select <strong>New > Class</strong>. Fill-in
+ the Name field as <em>HelloItemizedOverlay</em>. For the Superclass, enter
+ "com.google.android.maps.ItemizedOverlay". Click the checkbox for <em>Constructors from
+ superclass</em>. Click Finish.</p></li>
+
+ <li>First, you need an <code>OverlayItem</code> {@link java.util.ArrayList}, in which you'll put
+ each of the <code>OverlayItem</code> objects you want on the map. Add this at the top of the
+ <code>HelloItemizedOverlay</code> class:
+
+ <pre>private ArrayList&lt;OverlayItem> mOverlays = new ArrayList&lt;OverlayItem>();</pre>
+ </li>
+
+ <li>Now define the <code>HelloItemizedOverlay</code> constructors. The constructor must
+ define the default marker for each of the {@code OverlayItem}s. In order for the {@link
+ android.graphics.drawable.Drawable} to actually get drawn, it must have its bounds defined. Most
+ commonly, you want the center-point at the bottom of the image to be the point at which it's
+ attached to the map coordinates. This is handled for you with the {@code boundCenterBottom()}
+ method. Wrap this around our defaultMarker, so the super constructor call looks like this:
+<pre>
+public HelloItemizedOverlay(Drawable defaultMarker) {
+ super(boundCenterBottom(defaultMarker));
+}
+</pre>
+ </li>
+ <li>In order to add new {@code OverlayItem}s to the ArrayList, you need a new method:
<pre>
public void addOverlay(OverlayItem overlay) {
mOverlays.add(overlay);
populate();
}</pre>
+ <p>Each time you add a new {@code OverlayItem} to the ArrayList, you must call
+ <code>populate()</code> for the {@code ItemizedOverlay}, which will read each of the
+ {@code OverlayItem}s and prepare them to be drawn.</p>
+ </li>
- <p>Each time we add a new OverlayItem, we must call <code>populate()</code>, which will read each of out
- OverlayItems and prepare them to be drawn.</p></li>
-
- <li>In order for the <code>populate()</code> method to read each OverlayItem, it will make a request to
- <code>createItem(int)</code>. We must define this method to properly read from our ArrayList. Replace the
- existing contents of the createItem method with a <code>get()</code> call to our ArrayList:
+ <li>When the <code>populate()</code> method executes, it will call <code>createItem(int)</code> in
+ the {@code ItemizedOverlay} to retrieve each {@code OverlayItem}. You must override this method to
+ properly read from the ArrayList and return the {@code OverlayItem} from the position specified
+ by the given integer. Your override method should look like this:
<pre>
&#64;Override
protected OverlayItem createItem(int i) {
return mOverlays.get(i);
}
-</pre></li>
-
- <li>We're also required to override the <code>size()</code> method. Replace the existing contents of the
- method with a size request to our ArrayList:
+</pre>
+ </li>
- <pre>return mOverlays.size();</pre></li>
-</ol>
+ <li>You must also override the <code>size()</code> method to return the current number of
+ items in the ArrayList:
+<pre>
+&#64;Override
+public int size() {
+ return mOverlays.size();
+}
+</pre>
+ </li>
+ <li>Now set up the ability to handle touch events on the overlay items. First, you're
+ going to need a reference to the application {@link android.content.Context} as a member of
+ this class. So add {@code Context mContext} as a class member, then initialize it with a
+ new class constructor:
+<pre>
+public HelloItemizedOverlay(Drawable defaultMarker, Context context) {
+ super(defaultMarker);
+ mContext = context;
+}
+</pre>
+ <p>This passes the {@code defaultMarker} up to the default constructor to bound its coordinates
+ and then initialize {@code mContext} with the given {@link android.content.Context}.</p>
-<p>That's it for the HelloItemizedOverlay class. We're now ready to use it.</p>
+ <p>Then override the {@code onTap(int)} callback method, which will handle the event
+ when an item is tapped by the user:</p>
+<pre>
+&#64;Override
+protected boolean onTap(int index) {
+ OverlayItem item = mOverlays.get(index);
+ AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
+ dialog.setTitle(item.getTitle());
+ dialog.setMessage(item.getSnippet())
+ dialog.show();
+ return true;
+}
+</pre>
+ <p>This uses the member {@code android.content.Context} to create a new {@link
+android.app.AlertDialog.Builder} and uses the tapped {@code OverlayItem}'s title and snippet for
+the dialog's title and message text. (You'll see the {@code OverlayItem} title and snippet defined
+when you create it below.)</p>
+ </li>
-<hr/>
-<p>Go back to the HelloMapView
-class. We'll start by creating one OverlayItem, adding to an instance of our HelloItemizedOverlay,
-and then adding this to the MapView.</p>
+</ol>
-<img src="images/androidmarker.png" align="right" />
-<p>First, we need the image that we'll use for our map overlay. Here, we'll use the Android on the
-right as our marker. Drag this image (or your own) to the res/drawable/ directory of your project workspace.</p>
+<p>You're now done with the <code>HelloItemizedOverlay</code> class and can start using it
+to add items on the map.</p>
-<p>Now we're ready to work in the HelloMapView:</p>
+<p>Go back to the <code>HelloGoogleMaps</code> class. In the following procedure, you'll create an
+{@code OverlayItem} and add it to an instance of the <code>HelloItemizedOverlay</code> class, then
+add the <code>HelloItemizedOverlay</code> to the <code>MapView</code> using a {@code GeoPoint}
+to define its coordinates on the map.</p>
+<img src="images/androidmarker.png" align="right" />
<ol>
- <li>First we need some more types. Add the following at the top of the HelloMapView class:
-
-<pre>
-List&lt;Overlay> mapOverlays;
-Drawable drawable;
-HelloItemizedOverlay itemizedOverlay;</pre></li>
+ <li>First, you need the image for the map overlay. If you don't have one handy, use the Android on
+ the right. Drag this image (or your own) into the <code>res/drawable/</code> directory of your
+ project.</li>
- <li>Now pick up where we left off in the <code>onCreate()</code> method. Instantiate the
- new fields:
+ <li>At the end of your existing {@code onCreate()} method, instantiate :
<pre>
-mapOverlays = mapView.getOverlays();
-drawable = this.getResources().getDrawable(R.drawable.androidmarker);
-itemizedoverlay = new HelloItemizedOverlay(drawable);</pre>
-
- <p>All overlay elements on a map are held by the MapView, so when we want to add some, we must
- first retrieve the List with <code>getOverlays()</code> methods. We instantiate the Drawable, which will
- be used as our map marker, by using our Context resources to get the Drawable we placed in
- the res/drawable/ directory (androidmarker.png). Our HelloItemizedOverlay takes the Drawable in order to set the
- default marker.</p></li>
-
- <li>Now let's make our first OverlayItem by creating a GeoPoint
- that defines our map coordinates, then pass it to a new OverlayItem:
-
+List&lt;Overlay> mapOverlays = mapView.getOverlays();
+Drawable drawable = this.getResources().getDrawable(R.drawable.androidmarker);
+HelloItemizedOverlay itemizedoverlay = new HelloItemizedOverlay(drawable);</pre>
+
+ <p>All overlay elements on a map are held by the {@code MapView}, so when you want to add some,
+ you have to get a list from the <code>getOverlays()</code> method. Then instantiate the {@link
+ android.graphics.drawable.Drawable} used for the map marker, which was saved in the {@code
+ res/drawable/} directory. The constructor for {@code HelloItemizedOverlay} (your custom {@code
+ ItemizedOverlay}) takes the Drawable in order to set the default marker for all overlay
+ items.</p>
+ </li>
+
+ <li>Now create a {@code GeoPoint} that defines the map coordinates for the first overlay item,
+ and pass it to a new {@code OverlayItem}:
<pre>
GeoPoint point = new GeoPoint(19240000,-99120000);
-OverlayItem overlayitem = new OverlayItem(point, "", "");</pre>
-
- <p>GeoPoint coordinates are based in microdegrees (degrees * 1e6). The OverlayItem takes this
- GeoPoint and two strings. Here, we won't concern ourselves with the strings, which can display
- text when we click our marker, because we haven't yet written the click handler for the OverlayItem.</p></li>
+OverlayItem overlayitem = new OverlayItem(point, "Hola, Mundo!", "I'm in Mexico City!");
+</pre>
- <li>All that's left is for us to add this OverlayItem to our collection in the HelloItemizedOverlay,
- and add this to the List of Overlay objects retrieved from the MapView:
+ <p>{@code GeoPoint} coordinates are specified in microdegrees (<code>degrees * 1e6</code>). The
+ {@code OverlayItem} constructor accepts the {@code GeoPoint} location, a string for the
+ item's title, and a string for the item's snippet text, respectively.</p>
+ </li>
+ <li>All that's left is to add this {@code OverlayItem} to your collection in the
+ {@code HelloItemizedOverlay} instance, then add the {@code HelloItemizedOverlay} to the MapView:
<pre>
itemizedoverlay.addOverlay(overlayitem);
-mapOverlays.add(itemizedoverlay);</pre></li>
+mapOverlays.add(itemizedoverlay);
+</pre>
+ </li>
- <li>Run it!</li>
+ <li>Now run the application.</li>
</ol>
-<p>We've sent our droid to Mexico City. Hola, Mundo!</p>
<p>You should see the following:</p>
<img src="images/hello-mapview.png" width="150px" />
+<p>When you tap the overlay item, you'll see the dialog appear.</p>
-<p>Because we created our ItemizedOverlay class with an ArrayList, we can continue adding new
-OverlayItems. Try adding another one. Before the <code>addOverlay()</code> method is called, add these lines:</p>
+<p>Because the {@code ItemizedOverlay} class uses an {@code java.util.ArrayList} for all of the
+{@code OverlayItem}s, it's easy to add more. Try adding another one. Before the
+<code>addOverlay()</code> method is called, add these lines:</p>
<pre>
GeoPoint point2 = new GeoPoint(35410000, 139460000);
-OverlayItem overlayitem2 = new OverlayItem(point2, "", "");
+OverlayItem overlayitem2 = new OverlayItem(point2, "Sekai, konichiwa!", "I'm in Japan!");
</pre>
-<p>Run it again... We've sent a new droid to Tokyo. Sekai, konichiwa!</p>
+<p>Run the application again. (You probably need to move the map to find the new overlay item.)</p>
diff --git a/docs/html/resources/tutorials/views/hello-relativelayout.jd b/docs/html/resources/tutorials/views/hello-relativelayout.jd
index 1b91537..adc1179 100644
--- a/docs/html/resources/tutorials/views/hello-relativelayout.jd
+++ b/docs/html/resources/tutorials/views/hello-relativelayout.jd
@@ -1,33 +1,38 @@
-page.title=Hello, RelativeLayout
+page.title=Relative Layout
parent.title=Hello, Views
parent.link=index.html
@jd:body
-<p>A {@link android.widget.RelativeLayout} is a ViewGroup that allows you to layout child elements
-in positions relative to the parent or siblings elements.</p>
+<p>{@link android.widget.RelativeLayout} is a {@link android.view.ViewGroup} that displays
+child {@link android.view.View} elements in relative positions. The position of a {@link
+android.view.View} can be specified as relative to sibling elements (such as to the left-of or below
+a given element) or in positions relative to the {@link android.widget.RelativeLayout} area (such as
+aligned to the bottom, left of center).</p>
+
+<p>A {@link android.widget.RelativeLayout} is a very powerful utility for designing a user
+interface because it can eliminate nested {@link android.view.ViewGroup}s. If you find
+yourself using several nested {@link android.widget.LinearLayout} groups, you may be able to
+replace them with a single {@link android.widget.RelativeLayout}.</p>
<ol>
- <li>Start a new project/Activity called HelloRelativeLayout.</li>
- <li>Open the layout file. Make it like so:
+ <li>Start a new project named <em>HelloRelativeLayout</em>.</li>
+ <li>Open the <code>res/layout/main.xml</code> file and insert the following:
<pre>
&lt;?xml version="1.0" encoding="utf-8"?>
&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
-
&lt;TextView
android:id="@+id/label"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Type here:"/>
-
&lt;EditText
android:id="@+id/entry"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@android:drawable/editbox_background"
android:layout_below="@id/label"/>
-
&lt;Button
android:id="@+id/ok"
android:layout_width="wrap_content"
@@ -36,39 +41,48 @@ in positions relative to the parent or siblings elements.</p>
android:layout_alignParentRight="true"
android:layout_marginLeft="10dip"
android:text="OK" />
-
&lt;Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/ok"
android:layout_alignTop="@id/ok"
android:text="Cancel" />
-
&lt;/RelativeLayout>
</pre>
-<p>Pay attention to each of the additional <code>layout_*</code> attributes (besides the
-usual width and height, which are required for all elements). When using relative layout,
-we use attributes like <code>layout_below</code> and <code>layout_toLeftOf</code> to describe
-how we'd like to position each View. Naturally, these are different relative positions, and the
-value of the attribute is the id of the element we want the position relative to.</p>
+<p>Notice each of the <code>android:layout_*</code> attributes, such as <code>layout_below</code>,
+<code>layout_alignParentRight</code>, and <code>layout_toLeftOf</code>. When using a {@link
+android.widget.RelativeLayout}, you can use these attributes to describe
+how you want to position each {@link android.view.View}. Each one of these attributes define a
+different kind
+of relative position. Some attributes use the resource ID of a sibling {@link android.view.View}
+to define its own relative position. For example, the last {@link android.widget.Button} is
+defined to lie to the left-of and aligned-with-the-top-of the {@link android.view.View}
+identified by the ID <code>ok</code> (which is the previous {@link android.widget.Button}).</p>
+<p>All of the available layout attributes are defined in {@link
+android.widget.RelativeLayout.LayoutParams}.</p>
</li>
-<li>Make sure your Activity loads this layout in the <code>onCreate()</code> method:</p>
+<li>Make sure you load this layout in the
+{@link android.app.Activity#onCreate(Bundle) onCreate()} method:</p>
<pre>
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
</pre>
-<p><code>R.layout.main</code> refers to the <code>main.xml</code> layout file.</p>
+<p>The {@link android.app.Activity#setContentView(int)} method loads the
+layout file for the {@link android.app.Activity}, specified by the resource
+ID &mdash; <code>R.layout.main</code> refers to the <code>res/layout/main.xml</code> layout
+file.</p>
</li>
-<li>Run it.</li>
+<li>Run the application.</li>
</ol>
-<p>You should see the following:</p>
+<p>You should see the following layout:</p>
<img src="images/hello-relativelayout.png" width="150px" />
<h3>Resources</h3>
<ul>
<li>{@link android.widget.RelativeLayout}</li>
+ <li>{@link android.widget.RelativeLayout.LayoutParams}</li>
<li>{@link android.widget.TextView}</li>
<li>{@link android.widget.EditText}</li>
<li>{@link android.widget.Button}</li>
diff --git a/docs/html/resources/tutorials/views/hello-spinner.jd b/docs/html/resources/tutorials/views/hello-spinner.jd
index 3a04214..7a3a9c3 100644
--- a/docs/html/resources/tutorials/views/hello-spinner.jd
+++ b/docs/html/resources/tutorials/views/hello-spinner.jd
@@ -1,17 +1,17 @@
-page.title=Hello, Spinner
+page.title=Spinner
parent.title=Hello, Views
parent.link=index.html
@jd:body
-<p>A {@link android.widget.Spinner} is a widget that allows the user to select an item from a group.
-It is similar to a dropdown list and will allow scrolling when the
-list exceeds the available vertical space on the screen.</p>
+<p>{@link android.widget.Spinner} is a widget similar to a drop-down list for selecting items.</p>
+<p>In this tutorial, you'll create
+a simple spinner widget that displays a list of planets. When one is selected, a toast message
+will display the selected item.</p>
<ol>
- <li>Start a new project/Activity called HelloSpinner.</li>
- <li>Open the layout file.
- Make it like so:
+ <li>Start a new project named <em>HelloSpinner</em>.</li>
+ <li>Open the <code>res/layout/main.xml</code> file and insert the following:
<pre>
&lt;?xml version="1.0" encoding="utf-8"?>
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
@@ -19,41 +19,34 @@ list exceeds the available vertical space on the screen.</p>
android:padding="10dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
-
&lt;TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dip"
- android:text="Please select a planet:"
+ android:text="@string/planet_prompt"
/>
-
&lt;Spinner
android:id="@+id/spinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:drawSelectorOnTop="true"
android:prompt="@string/planet_prompt"
/>
-
&lt;/LinearLayout>
</pre>
- <p>Notice that the Spinner's <code>android:prompt</code> is a string resource. In
- this case, Android does not allow it to be a string, it must be a reference to a resource.
- So...</p>
-</li>
-
-<li>Open the strings.xml file in res/values/ and add the following <code>&lt;string></code>
-element inside the <code>&lt;resources></code> element:
-<pre>
-&lt;string name="planet_prompt">Choose a planet&lt;/string>
-</pre>
+ <p>Notice that the {@link android.widget.TextView}'s <code>android:text</code> attribute and the
+{@link android.widget.Spinner}'s <code>android:prompt</code> attribute both reference the same
+string resource. This text behaves as a title for the widget. When applied to the {@link
+android.widget.Spinner}, the title text will appear
+in the selection dialog that appears upon selecting the widget.</p>
</li>
-<li>Create a new XML file in res/values/ called arrays.xml. Insert the following:
+<li>Create a <code>strings.xml</code> file in <code>res/values/</code> and edit the file to look
+like this:
<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
&lt;resources>
-
- &lt;string-array name="planets">
+ &lt;string name="planet_prompt">Choose a planet&lt;/string>
+ &lt;string-array name="planets_array">
&lt;item>Mercury&lt;/item>
&lt;item>Venus&lt;/item>
&lt;item>Earth&lt;/item>
@@ -63,35 +56,85 @@ element inside the <code>&lt;resources></code> element:
&lt;item>Uranus&lt;/item>
&lt;item>Neptune&lt;/item>
&lt;/string-array>
-
&lt;/resources>
</pre>
- <p>This is the list of items (planets) that the user can select from in the Spinner widget.</p>
+ <p>The {@code &lt;string>} element defines the title string referenced by the {@link
+android.widget.TextView} and {@link android.widget.Spinner} in the layout above. The {@code
+&lt;string-array} element defines the list of strings that will be displayed as the list in
+the {@link android.widget.Spinner} widget.</p>
</li>
-<li>Now open the HelloSpinner.java file. Insert the following code into the HelloSpinner class:
+<li>Now open the <code>HelloSpinner.java</code> file and insert the following code for the {@link
+android.app.Activity#onCreate(Bundle) onCreate()} method:
<pre>
&#64;Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
- Spinner s = (Spinner) findViewById(R.id.spinner);
- ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
- this, R.array.planets, android.R.layout.simple_spinner_item);
+ Spinner spinner = (Spinner) findViewById(R.id.spinner);
+ ArrayAdapter&lt;CharSequence> adapter = ArrayAdapter.createFromResource(
+ this, R.array.planets_array, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- s.setAdapter(adapter);
+ spinner.setAdapter(adapter);
+}
+</pre>
+ <p>After the {@code main.xml} layout is set as the content view, the {@link
+android.widget.Spinner} widget is captured from the layout with {@link
+android.app.Activity#findViewById(int)}. The {@link
+android.widget.ArrayAdapter#createFromResource(Context,int,int) createFromResource()} method then
+creates a new {@link android.widget.ArrayAdapter}, which binds each item in the string array
+to the initial appearance for the {@link android.widget.Spinner} (which is how each item will
+appear in the spinner when selected). The {@code
+R.array.planets_array} ID references the {@code string-array} defined above and the
+{@code android.R.layout.simple_spinner_item} ID references a layout for the standard spinner
+appearance, defined by the platform. Then {@link
+android.widget.ArrayAdapter#setDropDownViewResource(int)} is called to define the appearance for
+each item when the widget is opened ({@code simple_spinner_dropdown_item} is
+another standard layout defined by the platform). Finally, the {@link android.widget.ArrayAdapter}
+is set to associate all of its items with the {@link android.widget.Spinner} by calling {@link
+android.widget.AdapterView#setAdapter(T)}.</p>
+</li>
+
+<li>Now create a nested class that implements {@link
+android.widget.AdapterView.OnItemSelectedListener}. This will provide a callback method that will
+notify your application when an item has been selected from the {@link
+android.widget.Spinner}. Here's what this class should look like:
+<pre>
+public class MyOnItemSelectedListener implements OnItemSelectedListener {
+
+ public void onItemSelected(AdapterView&lt;?> parent,
+ View view, int pos, long id) {
+ Toast.makeText(parent.getContext()), "The planet is " +
+ parent.getItemAtPosition(pos).toString(), Toast.LENGTH_LONG).show();
+ }
+
+ public void onNothingSelected(AdapterView<?> parent) {
+ // Do nothing.
+ }
}
</pre>
- <p>That's it. We start by creating a Spinner from our layout. We then create an {@link android.widget.ArrayAdapter}
- that binds each element of our string array to a layout view&mdash;we pass <code>createFromResource</code> our Context,
- the array of selectable items and the type of layout we'd like each one bound to. We then call
- <code>setDropDownViewResource()</code> to define the type of layout in which to present the
- entire collection. Finally, we set this Adapter to associate with our Spinner,
- so the string items have a place to go.</p>
+<p>The {@link android.widget.AdapterView.OnItemSelectedListener} requires the {@link
+android.widget.AdapterView.OnItemSelectedListener#onItemSelected(AdapterView,View,int,long)
+onItemSelected()} and {@link
+android.widget.AdapterView.OnItemSelectedListener#onNothingSelected(AdapterView)
+onNothingSelected()} callback methods. The former is called when an item from the {@link
+android.widget.AdapterView} is selected, in which case, a short {@link android.widget.Toast}
+message displays the selected text; and the latter is called when a selection disappears from the
+{@link android.widget.AdapterView}, which doesn't happen in this case, so it's ignored.</p>
+</li>
+
+<li>Now the {@code MyOnItemSelectedListener} needs to be applied to the {@link
+android.widget.Spinner}. Go back to the {@link android.app.Activity#onCreate(Bundle) onCreate()}
+method and add the following line to the end:
+<pre>
+ spinner.setOnItemSelectedListener(new MyOnItemSelectedListener());
+</pre>
+<p>This creates a new anonymous instance of the {@code MyOnItemSelectedListener} and sets it as the
+listener for the {@link android.widget.Spinner}.</p>
</li>
-<li>Now run it.</li>
+<li>Run the application.</li>
</ol>
<p>It should look like this:</p>
<img src="images/hello-spinner.png" width="150px" />
diff --git a/docs/html/resources/tutorials/views/hello-tablelayout.jd b/docs/html/resources/tutorials/views/hello-tablelayout.jd
index 83d6f5d..c8c5982 100644
--- a/docs/html/resources/tutorials/views/hello-tablelayout.jd
+++ b/docs/html/resources/tutorials/views/hello-tablelayout.jd
@@ -1,16 +1,15 @@
-page.title=Hello, TableLayout
+page.title=Table Layout
parent.title=Hello, Views
parent.link=index.html
@jd:body
-<p>A {@link android.widget.TableLayout} is a ViewGroup that
-will lay child View elements into rows and columns.</p>
+<p>{@link android.widget.TableLayout} is a {@link android.view.ViewGroup} that
+displays child {@link android.view.View} elements in rows and columns.</p>
<ol>
- <li>Start a new project/Activity called HelloTableLayout.</li>
- <li>Open the layout file.
- Make it like so:
+ <li>Start a new project named <em>HelloTableLayout</em>.</li>
+ <li>Open the <code>res/layout/main.xml</code> file and insert the following:
<pre>
&lt;?xml version="1.0" encoding="utf-8"?>
&lt;TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
@@ -89,21 +88,28 @@ will lay child View elements into rows and columns.</p>
&lt;/TableRow>
&lt;/TableLayout>
</pre>
-<p>Notice how this resembles the structure of an HTML table. <code>TableLayout</code> is like the
-<code>table</code> element; <code>TableRow</code> is like a <code>tr</code> element; but for our cells like
-the html <code>td</code> element, we can use any kind of View. Here, we use <code>TextView</code> for the cells.</p>
+<p>Notice how this resembles the structure of an HTML table. The {@link android.widget.TableLayout}
+element is like the HTML <code>&lt;table&gt;</code> element; {@link android.widget.TableRow} is like
+a <code>>&lt;tr>&gt;</code> element;
+but for the cells, you can use any kind of {@link android.view.View} element. In this example, a
+{@link android.widget.TextView} is used for each cell. In between some of the rows, there is also a
+basic {@link android.view.View}, which is used to draw a horizontal line.</p>
</li>
-<li>Make sure your Activity loads this layout in the <code>onCreate()</code> method:
+<li>Make sure your <em>HelloTableLayout</em> Activity loads this layout in the
+{@link android.app.Activity#onCreate(Bundle) onCreate()} method:
<pre>
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
</pre>
-<p><code>R.layout.main</code> refers to the <code>main.xml</code> layout file.</p>
+<p>The {@link android.app.Activity#setContentView(int)} method loads the
+layout file for the {@link android.app.Activity}, specified by the resource
+ID &mdash; <code>R.layout.main</code> refers to the <code>res/layout/main.xml</code> layout
+file.</p>
</li>
-<li>Run it.</li>
+<li>Run the application.</li>
</ol>
<p>You should see the following:</p>
<img src="images/hello-tablelayout.png" width="150px" />
diff --git a/docs/html/resources/tutorials/views/hello-tabwidget.jd b/docs/html/resources/tutorials/views/hello-tabwidget.jd
index 8424616..199ceef 100644
--- a/docs/html/resources/tutorials/views/hello-tabwidget.jd
+++ b/docs/html/resources/tutorials/views/hello-tabwidget.jd
@@ -1,14 +1,72 @@
-page.title=Hello, TabWidget
+page.title=Tab Layout
parent.title=Hello, Views
parent.link=index.html
@jd:body
-<p>A {@link android.widget.TabWidget} offers the ability to easily draw an interface that uses
-tabs to navigate between different views.</p>
+<p>To create a tabbed UI, you need to use a {@link android.widget.TabHost} and a {@link
+android.widget.TabWidget}. The {@link android.widget.TabHost} must be the root node for the layout,
+which contains both the {@link android.widget.TabWidget} for displaying the tabs and a {@link
+android.widget.FrameLayout} for displaying the tab content.</p>
+
+<p>You can implement your tab content in one of two ways: use the tabs to swap
+{@link android.view.View}s within the same {@link android.app.Activity}, or use the tabs to change
+between entirely separate activities. Which method you want for your application will depend on your
+demands, but if each tab provides a distinct user activity, then it probably makes sense to use
+a separate {@link android.app.Activity} for each tab, so that you can better manage the application
+in discrete groups, rather than one massive application and layout.</p>
+
+<p>In this tutorial, you'll create a tabbed UI that uses a separate {@link
+android.app.Activity} for each tab.</p>
<ol>
- <li>Start a new project/Activity called HelloTabWidget.</li>
- <li>Open the layout file and make it like so:</li>
+ <li>Start a new project named <em>HelloTabWidget</em>.</li>
+ <li>First, create three separate {@link android.app.Activity} classes in your project:
+<code>ArtistsActivity</code>, <code>AlbumsActivity</code>, and <code>SongsActivity</code>. These
+will each represent a separate tab. For now, make each one display a simple message using a {@link
+android.widget.TextView}. For example:
+<pre>
+public class ArtistsActivity extends Activity {
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ TextView textview = new TextView(this);
+ textview.setText("This is the Artists tab");
+ setContentView(textview);
+ }
+}
+</pre>
+ <p>Notice that this doesn't use a layout file. Just create a {@link
+android.widget.TextView}, give it some text and set that as the content. Duplicate this for
+each of the three activities.</p>
+
+ <li>You're going to need an icon for each of your tabs. And for each one, you should create an
+image for two different states: one for when the tab is selected, and one for when it is not. The
+general design recommendation is for the selected tab icon to be a darker color (grey), and the
+non-selected icon to be lighter (white). For example:
+ <p>
+ <img src="images/ic_tab_artists_white.png" title="ic_tab_artists_white.png" alt="" />
+ <img src="images/ic_tab_artists_grey.png" title="ic_tab_artists_grey.png" alt="" />
+ </p>
+ <p>Copy these images for use in this tutorial. Save them into your project
+<code>res/drawable/</code> directory. You now need to create a {@link
+android.graphics.drawable.Drawable} with XML that specifies which image
+to use for each state. Create a new file in <code>res/drawable/</code> named
+<code>ic_tab_artists.xml</code> and insert the following:</p>
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;selector xmlns:android="http://schemas.android.com/apk/res/android">
+ &lt;!-- When selected, use grey -->
+ &lt;item android:drawable="@drawable/ic_tab_artists_grey"
+ android:state_selected="true" />
+ &lt;!-- When not selected, use white-->
+ &lt;item android:drawable="@drawable/ic_tab_artists_white" />
+&lt;/selector>
+</pre>
+ <p>This is an XML definition for a {@link android.graphics.drawable.Drawable}, which you will
+reference as the image for a tab. When the image state changes, the image will automatically
+switch between the images defined here.</p>
+
+ <li>Open the <code>res/layout/main.xml</code> file and insert the following:
<pre>
&lt;?xml version="1.0" encoding="utf-8"?>
&lt;TabHost xmlns:android="http://schemas.android.com/apk/res/android"
@@ -18,7 +76,8 @@ tabs to navigate between different views.</p>
&lt;LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
- android:layout_height="fill_parent">
+ android:layout_height="fill_parent"
+ android:padding="5dp">
&lt;TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
@@ -26,94 +85,111 @@ tabs to navigate between different views.</p>
&lt;FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- &lt;TextView
- android:id="@+id/textview1"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:text="this is a tab" />
- &lt;TextView
- android:id="@+id/textview2"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:text="this is another tab" />
- &lt;TextView
- android:id="@+id/textview3"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:text="this is a third tab" />
- &lt;/FrameLayout>
+ android:layout_height="fill_parent"
+ android;padding="5dp" />
&lt;/LinearLayout>
&lt;/TabHost>
</pre>
- <p>Here, we've created a {@link android.widget.TabHost} that contains the entire layout of the Activity.
- A TabHost requires two descendant elements: a {@link android.widget.TabWidget} and a {@link android.widget.FrameLayout}.
- In order to properly layout these elements, we've put them inside a vertical {@link android.widget.LinearLayout}.
- The FrameLayout is where we keep the content that will change with each tab. Each child in the FrameLayout will
- be associated with a different tab.
- In this case, each tab simply shows a different {@link android.widget.TextView} with some text. </p>
- <p>Notice that the TabWidget and the FrameLayout elements have specific <code>android</code> namespace IDs. These are necessary
- so that the TabHost can automatically retireve references to them, populate the TabWidget with the tabs that we'll define
- in our code, and swap the views in the FrameLayout. We've also defined our own IDs for each TextView, which we'll use to
- associate each tab with the view that it should reveal.</p>
- <p>Of course, you can
- make these child views as large as complex as you'd like &mdash; instead of the TextView elements,
- you could start with other layout views and build a unique layout hierarchy for each tab.</p>
+ <p>This is the layout that will display the tabs and provide navigation between each {@link
+ android.app.Activity} created above.</p>
+ <p>The {@link android.widget.TabHost} requires that a {@link android.widget.TabWidget} and a
+{@link android.widget.FrameLayout} both live somewhere within it. To position the {@link
+android.widget.TabWidget} and {@link android.widget.FrameLayout} vertically, a {@link
+android.widget.LinearLayout} is used. The {@link android.widget.FrameLayout} is where the content
+for each tab goes, which is empty now because the {@link android.widget.TabHost} will automatically
+embed each {@link android.app.Activity} within it.</p>
+ <p>Notice that the {@link android.widget.TabWidget} and the {@link android.widget.FrameLayout}
+ elements have the IDs {@code tabs} and {@code tabcontent}, respectively. These names
+ must be used so that the {@link android.widget.TabHost} can retrieve references to each of
+ them. It expects exactly these names.</p>
</li>
- <li>Now we'll add our code. Open HelloTabWidget.java and make it a <code>TabActivity</code>.
- <p>By default, Eclipse creates a class that extends <code>Activity</code>. Change it to
- extend <code>TabActivity</code>:</p>
- <pre>
+
+ <li>Now open <code>HelloTabWidget.java</code> and make it extend {@link
+ android.app.TabActivity}:</p>
+<pre>
public class HelloTabWidget extends TabActivity {
-</pre>
+</pre>
</li>
- <li>Now fill in the the <code>onCreate</code> method like this:
- <pre>
+ <li>Use the following code for the {@link android.app.Activity#onCreate(Bundle) onCreate()}
+ method:
+<pre>
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
- mTabHost = getTabHost();
-
- mTabHost.addTab(mTabHost.newTabSpec("tab_test1").setIndicator("TAB 1").setContent(R.id.textview1));
- mTabHost.addTab(mTabHost.newTabSpec("tab_test2").setIndicator("TAB 2").setContent(R.id.textview2));
- mTabHost.addTab(mTabHost.newTabSpec("tab_test3").setIndicator("TAB 3").setContent(R.id.textview3));
-
- mTabHost.setCurrentTab(0);
+ Resources res = getResources(); // Resource object to get Drawables
+ TabHost tabHost = getTabHost(); // The activity TabHost
+ TabHost.TabSpec spec; // Resusable TabSpec for each tab
+ Intent intent; // Reusable Intent for each tab
+
+ // Create an Intent to launch an Activity for the tab (to be reused)
+ intent = new Intent().setClass(this, ArtistsActivity.class);
+
+ // Initialize a TabSpec for each tab and add it to the TabHost
+ spec = tabHost.newTabSpec("artists").setIndicator("Artists",
+ res.getDrawable(R.drawable.ic_tab_artists))
+ .setContent(intent);
+ tabHost.addTab(spec);
+
+ // Do the same for the other tabs
+ intent = new Intent().setClass(this, AlbumsActivity.class);
+ spec = tabHost.newTabSpec("albums").setIndicator("Albums",
+ res.getDrawable(R.drawable.ic_tab_albums))
+ .setContent(intent);
+ mTabHost.addTab(spec);
+
+ intent = new Intent().setClass(this, SongsActivity.class);
+ spec = tabHost.newTabSpec("songs").setIndicator("Songs",
+ res.getDrawable(R.drawable.ic_tab_songs))
+ .setContent(intent);
+ tabHost.addTab(spec);
+
+ tabHost.setCurrentTab(getIntent());
}
</pre>
- <p>As usual, we start by setting our layout.</p>
- <p>We then call the TabActivity method <code>getTabHost()</code>,
- which returns us a reference to the TabHost we created in our layout. Upon our TabHost, we call <code>addTab()</code>
- for each of the tabs that we want to add to the TabWidget. Each time we call this, we pass a
- {@link android.widget.TabHost.TabSpec} that we build on the fly, and with it, chain together two necessary methods:
- <code>setIndicator()</code> to set the text for the tab button, and <code>setContent()</code> to define
- which View we want to associate with the tab and reveal when pressed. Our indicator is just a text string and
- our content is an ID reference to the TextView elements we inserted in the FrameLayout.</p>
- <p>At the end, we call <code>setCurrentTab()</code> to define which tab should be opened by default. The tabs
- are saved like a zero-based array, so to open the first tab, we pass zero (<var>0</var>).</p>
+ <p>This sets up each tab with their text and icon, and assigns each one an {@link
+android.app.Activity}.</p>
+ <p>A reference to the {@link android.widget.TabHost} is first captured with {@link
+android.app.TabActivity#getTabHost()}. Then, for
+each tab, a {@link android.widget.TabHost.TabSpec} is created to define the tab properties. The
+{@link android.widget.TabHost#newTabSpec(String)} method creates a new {@link
+android.widget.TabHost.TabSpec} identified by the given string tag. For each
+{@link android.widget.TabHost.TabSpec}, {@link
+android.widget.TabHost.TabSpec#setIndicator(CharSequence,Drawable)} is called to set the text and
+icon for the tab, and {@link android.widget.TabHost.TabSpec#setContent(Intent)} is called to specify
+the {@link android.content.Intent} to opens the appropriate {@link android.app.Activity}. Each
+{@link android.widget.TabHost.TabSpec} is then added to the {@link android.widget.TabHost} by
+calling {@link android.widget.TabHost#addTab(TabHost.TabSpec)}.</p>
+
+ <p>At the very end, {@link
+ android.widget.TabHost#setCurrentTab(int)} opens the tab to be displayed by default, specified
+ by the index position of the tab.</p>
+
+ <p>Notice that not once was the {@link android.widget.TabWidget} object referenced. This is
+ because a {@link android.widget.TabWidget} must always be a child of a {@link
+ android.widget.TabHost}, which is what you use for almost all interaction with the tabs. So when
+ a tab is added to the {@link android.widget.TabHost}, it's automatically added to the child
+ {@link android.widget.TabWidget}.</p>
</li>
- <li>To clean-up the presentation a bit more, let's remove the window title that appears at the top of the layout.
- Android includes a theme that removes that title for us. To add it, open the Android Manifest file and add
- the <var>NoTitleBar</var> theme to the <code>&lt;application></code> tag. It should end up like this:
- <pre>
-&lt;application android:icon="&#64;drawable/icon" android:theme="&#64;android:style/Theme.NoTitleBar">
+
+ <li>Now open the Android Manifest file and add the <code>NoTitleBar</code> theme to the
+<em>HelloTabWidget</em>'s
+ <code>&lt;activity></code> tag. This will remove the default application title from the top
+ of the layout, leaving more space for the tabs, which effectively operate as their own titles.
+ The <code>&lt;activity></code> tag should look like this:
+<pre>
+&lt;activity android:name=".HelloTabWidget" android:label="@string/app_name"
+ android:theme="&#64;android:style/Theme.NoTitleBar">
</pre>
</li>
- <li>That's it. Run your application.</li>
+ <li>Run the application.</li>
</ol>
<p>Your application should look like this:</p>
<img src="images/hello-tabwidget.png" width="150px" />
-<div class="special"><p>You can include icons in your tabs by passing a
-{@link android.graphics.drawable.Drawable} when you call <code>setIndicator()</code>. Here's an example
-that uses a Drawable created from an image in the project resources:</p>
-<pre>setIndicator("TAB 1", getResources().getDrawable(R.drawable.tab_icon))</pre>
-</div>
-
<h3>References</h3>
<ul>
<li>{@link android.widget.TabWidget}</li>
diff --git a/docs/html/resources/tutorials/views/hello-timepicker.jd b/docs/html/resources/tutorials/views/hello-timepicker.jd
index 1a6c8f9..cf16c8e 100644
--- a/docs/html/resources/tutorials/views/hello-timepicker.jd
+++ b/docs/html/resources/tutorials/views/hello-timepicker.jd
@@ -1,106 +1,97 @@
-page.title=Hello, TimePicker
+page.title=Time Picker
parent.title=Hello, Views
parent.link=index.html
@jd:body
-<p>A {@link android.widget.TimePicker} is a widget that allows the
-user to select the time by hour, minute and AM or PM.</p>
+<p>To provide a widget for selecting a time, use the {@link android.widget.TimePicker}
+widget, which allows the user to select the hour and minute in a familiar interface.</p>
+<p>In this tutorial, you'll create a {@link android.app.TimePickerDialog}, which presents the
+time picker in a floating dialog box at the press of a button. When the time is set by
+the user, a {@link android.widget.TextView} will update with the new date.</p>
<ol>
- <li>Start a new project/Activity called HelloTimePicker.</li>
- <li>Open the layout file and make it like so:
+ <li>Start a new project named <em>HelloTimePicker</em>.</li>
+ <li>Open the <code>res/layout/main.xml</code> file and insert the following:
<pre>
&lt;?xml version="1.0" encoding="utf-8"?>
&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
-
&lt;TextView android:id="@+id/timeDisplay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""/>
-
&lt;Button android:id="@+id/pickTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Change the time"/>
-
&lt;/LinearLayout>
</pre>
- <p>For the layout, we're using a vertical LinearLayout, with a {@link android.widget.TextView} that
- will display the time and a {@link android.widget.Button} that will initiate the
- {@link android.widget.TimePicker} dialog.
- With this layout, the TextView will sit above the Button.
- The text value in the TextView is set empty, as it will be filled by our Activity
- with the current time.</p>
- </li>
-
- <li>Open HelloTimePicker.java. Insert the following to the HelloTimePicker class:
-<pre>
-private TextView mTimeDisplay;
-private Button mPickTime;
-
-private int mHour;
-private int mMinute;
-
-static final int TIME_DIALOG_ID = 0;
+<p>This is a basic {@link android.widget.LinearLayout} with a {@link android.widget.TextView}
+that will display the time and a {@link android.widget.Button} that will open the {@link
+android.app.TimePickerDialog}.</p>
+ </li>
-&#64;Override
-protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
-
- // capture our View elements
- mTimeDisplay = (TextView) findViewById(R.id.timeDisplay);
- mPickTime = (Button) findViewById(R.id.pickTime);
-
- // add a click listener to the button
- mPickTime.setOnClickListener(new View.OnClickListener() {
- public void onClick(View v) {
- showDialog(TIME_DIALOG_ID);
- }
- });
+ <li>Open <code>HelloTimePicker.java</code> and insert the following class members:
+<pre>
+ private TextView mTimeDisplay;
+ private Button mPickTime;
- // get the current time
- final Calendar c = Calendar.getInstance();
- mHour = c.get(Calendar.HOUR_OF_DAY);
- mMinute = c.get(Calendar.MINUTE);
+ private int mHour;
+ private int mMinute;
- // display the current date
- updateDisplay();
-}
+ static final int TIME_DIALOG_ID = 0;
</pre>
-<p class="note"><strong>Tip:</strong> Press Ctrl(or Cmd) + Shift + O to import all needed packages.</p>
- <p>We start by instantiating variables for our View elements and time fields.
- The <code>TIME_DIALOG_ID</code> is a static integer that uniquely identifies the dialog. In the
- <code>onCreate()</code> method, we get prepared by setting the layout and capturing the View elements.
- We then set an on-click listener for the Button, so that when it is clicked, it will
- show our TimePicker dialog. The <code>showDialog()</code> method will perform a callback
- to our Activity. (We'll define this callback in the next section.) We then create an
- instance of {@link java.util.Calendar} and get the current hour and minute. Finally, we call
- <code>updateDisplay()</code>&mdash;our own method that will fill the TextView with the time.</p>
-</li>
-
-<li>After the <code>onCreate()</code> method, add the <code>onCreateDialog()</code> callback method:
+<p>This declares variables for the layout elements and time fields.
+The <code>TIME_DIALOG_ID</code> is a static integer that uniquely identifies the dialog.</p>
+ </li>
+ <li>Now insert the following code for the {@link android.app.Activity#onCreate(Bundle) onCreate()}
+method:
<pre>
-&#64;Override
-protected Dialog onCreateDialog(int id) {
- switch (id) {
- case TIME_DIALOG_ID:
- return new TimePickerDialog(this,
- mTimeSetListener, mHour, mMinute, false);
+ &#64;Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+
+ // capture our View elements
+ mTimeDisplay = (TextView) findViewById(R.id.timeDisplay);
+ mPickTime = (Button) findViewById(R.id.pickTime);
+
+ // add a click listener to the button
+ mPickTime.setOnClickListener(new View.OnClickListener() {
+ public void onClick(View v) {
+ showDialog(TIME_DIALOG_ID);
+ }
+ });
+
+ // get the current time
+ final Calendar c = Calendar.getInstance();
+ mHour = c.get(Calendar.HOUR_OF_DAY);
+ mMinute = c.get(Calendar.MINUTE);
+
+ // display the current date
+ updateDisplay();
}
- return null;
-}
</pre>
- <p>This is passed the identifier we gave <code>showDialog()</code> and initializes
- the TimePicker to the time we retrieved from our Calendar instance. It will be called by
- <code>showDialog()</code>.</p>
+
+<p>First, the content is set to the <code>main.xml</code> layout and then the {@link
+android.widget.TextView} and {@link android.widget.Button} are captured with {@link
+android.app.Activity#findViewById(int)}.
+Then an {@link android.view.View.OnClickListener} is created for the {@link android.widget.Button},
+so that when clicked, it will call {@link
+android.app.Activity#showDialog(int)}, passing the unique integer ID for the time picker
+dialog. Using {@link android.app.Activity#showDialog(int)} allows the {@link
+android.app.Activity} to manage the life-cycle of the dialog and will call the {@link
+android.app.Activity#onCreateDialog(int)} callback method to request the {@link android.app.Dialog}
+that should be displayed (which you'll define later). After the on-click listener is set, a new
+{@link java.util.Calendar} is created to get the current hour and minute. Finally, the
+private <code>updateDisplay()</code> method is called in order to fill the {@link
+android.widget.TextView} with the current time.</p>
</li>
-<li>Now add our <code>updateDisplay()</code> method:
+<li>Add the <code>updateDisplay()</code> and <code>pad()</code> methods:
<pre>
// updates the time we display in the TextView
private void updateDisplay() {
@@ -109,13 +100,22 @@ private void updateDisplay() {
.append(pad(mHour)).append(":")
.append(pad(mMinute)));
}
+
+private static String pad(int c) {
+ if (c >= 10)
+ return String.valueOf(c);
+ else
+ return "0" + String.valueOf(c);
+}
</pre>
- <p>This simply takes our member fields for the time and inserts them in
- the <code>mTimeDisplay</code> TextView. Note that we call a new method, <code>pad()</code>,
- on the hour and minute. (We'll create this method in the last step.)</p>
+<p>The <code>updateDisplay()</code> method uses the member fields for the time and inserts them in
+the <code>mTimeDisplay</code> {@link android.widget.TextView}. The <code>pad()</code> method returns
+the appropriate string representation of the hour or minute&mdash;it will prefix a zero to the
+number if it's a single digit.</p>
</li>
-<li>Next, add a listener to be called when the time is reset:
+<li>Add a class member for a {@link android.app.TimePickerDialog.OnTimeSetListener} that will be
+called when the user sets a new time:
<pre>
// the callback received when the user "sets" the time in the dialog
private TimePickerDialog.OnTimeSetListener mTimeSetListener =
@@ -127,24 +127,31 @@ private TimePickerDialog.OnTimeSetListener mTimeSetListener =
}
};
</pre>
- <p>Now when the user is done setting the time (clicks the "Set" button), we update our member fields with
- the new time and update our TextView.</p>
+<p>When the user is done setting the time (clicks the "Set" button), the
+<code>onTimeSet()</code> method is called and it updates the member fields with
+the new time and updates the layout's {@link android.widget.TextView}.</p>
</li>
-<li>Finally, add the <code>pad()</code> method that we called from the <code>updateDisplay()</code>:
+
+<li>Add the {@link android.app.Activity#onCreateDialog(int)} callback method:
<pre>
-private static String pad(int c) {
- if (c >= 10)
- return String.valueOf(c);
- else
- return "0" + String.valueOf(c);
+&#64;Override
+protected Dialog onCreateDialog(int id) {
+ switch (id) {
+ case TIME_DIALOG_ID:
+ return new TimePickerDialog(this,
+ mTimeSetListener, mHour, mMinute, false);
+ }
+ return null;
}
</pre>
- <p>This method returns the appropriate String representation of the hour or minute.
- It will prefix a zero to the number if it's a single digit.
- </p>
+<p>This is an {@link android.app.Activity} callback that is passed the identifier you passed to
+{@link android.app.Activity#showDialog(int)}, in the {@link android.widget.Button}'s on-click
+listener. When the ID matches, this initializes the {@link android.app.TimePickerDialog} with the
+member variables initialized at the end of <code>onCreate()</code> and the {@link
+android.app.TimePickerDialog.OnTimeSetListener} created in the previous step.</p>
</li>
-<li>Now run it.</li>
+<li>Run the application.</li>
</ol>
<p>When you press the "Change the time" button, you should see the following:</p>
<img src="images/hello-timepicker.png" width="150px" />
@@ -152,6 +159,7 @@ private static String pad(int c) {
<h3>References</h3>
<ol>
<li>{@link android.widget.TimePicker}</li>
+ <li>{@link android.app.TimePickerDialog.OnTimeSetListener}</li>
<li>{@link android.widget.Button}</li>
<li>{@link android.widget.TextView}</li>
<li>{@link java.util.Calendar}</li>
diff --git a/docs/html/resources/tutorials/views/hello-webview.jd b/docs/html/resources/tutorials/views/hello-webview.jd
index c4388ea..17b2646 100644
--- a/docs/html/resources/tutorials/views/hello-webview.jd
+++ b/docs/html/resources/tutorials/views/hello-webview.jd
@@ -1,63 +1,72 @@
-page.title=Hello, WebView
+page.title=Web View
parent.title=Hello, Views
parent.link=index.html
@jd:body
-<p>A {@link android.webkit.WebView} allows you to create your own web browser Activity. In this tutorial,
-we'll create a simple Activity that can view web pages.</p>
+<p>{@link android.webkit.WebView} allows you to create your own window for viewing web pages (or even
+develop a complete browser). In this tutorial, you'll create a simple {@link android.app.Activity}
+that can view and navigate web pages.</p>
<ol>
- <li>Create a new project/Activity called HelloWebView.</li>
- <li>Open the layout file. Insert a WebView so it looks like so:
+ <li>Create a new project named <em>HelloWebView</em>.</li>
+ <li>Open the <code>res/layout/main.xml</code> file and insert the following:
<pre>
&lt;?xml version="1.0" encoding="utf-8"?>
-&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="vertical">
-
- &lt;WebView
- android:id="@+id/webview"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- />
-
-&lt;/LinearLayout>
-</pre></li>
+&lt;WebView
+ android:id="@+id/webview"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+/>
+</pre>
+ </li>
- <li>Now open the HelloWebView.java file.
- At the top of the class, instantiate a WebView object:
-<pre>WebView webview;</pre>
- <p> Then add the following at the end of the <code>onCreate()</code> method:</p>
+ <li>Now open the <code>HelloWebView.java</code> file.
+ At the top of the class, declare a {@link android.webkit.WebView} object:
+<pre>WebView mWebView;</pre>
+ <p>Then use the following code for the {@link android.app.Activity#onCreate(Bundle) onCreate()}
+ method:</p>
<pre>
-webview = (WebView) findViewById(R.id.webview);
-webview.getSettings().setJavaScriptEnabled(true);
-webview.loadUrl("http://www.google.com");
+public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+
+ mWebView = (WebView) findViewById(R.id.webview);
+ mWebView.getSettings().setJavaScriptEnabled(true);
+ mWebView.loadUrl("http://www.google.com");
+}
</pre>
-
- <p>This captures the WebView we created in our layout, then requests a
- {@link android.webkit.WebSettings} object and enables JavaScript.
- Then we load a URL.</p></li>
-
- <li>Because we're accessing the internet, we need to add the appropriate
- permissions to the Android manifest file. So open the AndroidManifest.xml file
- and, add the following as a child of the <code>&lt;manifest></code> element:
-
- <pre>&lt;uses-permission android:name="android.permission.INTERNET" /></pre></li>
-
- <li>Now run it.</li>
-</ol>
-<p> You now have the world's simplest web page viewer.
- It's not quite a browser yet. It only loads the page we've requested.</p>
-
-<hr/>
-
-<p>We can load a page, but as soon as we click a link, the default Android web browser
-handles the Intent, instead of our own WebView handling the action. So now we'll
-override the {@link android.webkit.WebViewClient} to enable us to handle our own URL loading.</p>
-
-<ol>
- <li>In the HelloAndroid Activity, add this nested private class:
+ <p>This initializes the member {@link android.webkit.WebView} with the one from the
+ {@link android.app.Activity} layout; requests a {@link android.webkit.WebSettings} object with
+ {@link android.webkit.WebView#getSettings()}; and enables JavaScript for the {@link
+ android.webkit.WebView} with {@link android.webkit.WebSettings#setJavaScriptEnabled(boolean)}.
+ Finally, an initial web page is loaded with {@link
+ android.webkit.WebView#loadUrl(String)}.</p>
+ </li>
+
+ <li>Because this application needs access to the Internet, you need to add the appropriate
+ permissions to the Android manifest file. Open the <code>AndroidManifest.xml</code> file
+ and add the following as a child of the <code>&lt;manifest></code> element:
+
+ <pre>&lt;uses-permission android:name="android.permission.INTERNET" /></pre></li>
+
+ <li>While you're in the manifest, give some more space for web pages by removing the title
+ bar, with the "NoTitleBar" theme:
+<pre>
+&lt;activity android:name=".HelloGoogleMaps" android:label="@string/app_name"
+ <strong>android:theme="@android:style/Theme.NoTitleBar"</strong>&gt;
+</pre>
+ </li>
+
+ <li>Now run the application.
+ <p>You now have a simplest web page viewer.
+ It's not quite a browser yet because as soon as you click a link, the default Android Browser
+ handles the Intent to view a web page, because this {@link android.app.Activity} isn't
+ technically enabled to do so. Instead of adding an intent filter to view web pages, you can
+ override the {@link android.webkit.WebViewClient} class and enable this {@link
+ android.app.Activity} to handle its own URL requests.</p>
+ </li>
+
+ <li>In the <code>HelloAndroid</code> Activity, add this nested class:
<pre>
private class HelloWebViewClient extends WebViewClient {
&#64;Override
@@ -65,42 +74,51 @@ private class HelloWebViewClient extends WebViewClient {
view.loadUrl(url);
return true;
}
-}</pre></li>
-
- <li>Now, in the <code>onCreate()</code> method, set an instance of the <code>HelloWebViewClient</code>
- as our WebViewClient:
- <pre>webview.setWebViewClient(new WebViewClientDemo());</pre>
-
- <p>This line should immediately follow the initialization of our WebView object.</p>
- <p>What we've done is create a WebViewClient that will load any URL selected in our
-WebView in the same WebView. You can see this in the <code>shouldOverrideUrlLoading()</code>
-method, above&mdash;it is passed the current WebView and the URL, so all we do
-is load the URL in the given view. Returning <var>true</var> says that we've handled the URL
-ourselves and the event should not bubble-up.</p>
- <p>If you try it again, new pages will now load in the HelloWebView Activity. However, you'll notice that
-we can't navigate back. We need to handle the back button
-on the device, so that it will return to the previous page, rather than exit the application.</p>
+}
+</pre>
+ </li>
+ <li>Then towards the end of the {@link android.app.Activity#onCreate(Bundle)} method, set an
+ instance of the <code>HelloWebViewClient</code> as the {@link android.webkit.WebViewClient}:
+ <pre>mWebView.setWebViewClient(new WebViewClientDemo());</pre>
+
+ <p>This line can go anywhere following the initialization of the {@link
+ android.webkit.WebView} object.</p>
+ <p>This creates a {@link android.webkit.WebViewClient} that will load any URL selected from this
+ {@link android.webkit.WebView} into the same {@link android.webkit.WebView}. The
+ {@link android.webkit.WebViewClient#shouldOverrideUrlLoading(WebView,String)} method is passed
+the current {@link android.webkit.WebView} and the URL requested, so all it needs to do is load
+the URL in the given view. Returning <code>true</code> says that the method has handled the URL
+and the event should not propagate (in which case, an Intent would be created that's handled by
+the Browser application).</p>
+ <p>If you run the application again, new pages will now load in this Activity.
+ However, you can't navigate back to previous pages. To do this, you need to handle the BACK
+ button on the device, so that it will return to the previous page, rather than exit the
+ application.</p>
</li>
- <li>To handle the back button key press, add the following method inside the HelloWebView
-Activity:
+ <li>To handle the BACK button key press, add the following method inside the
+ <code>HelloWebView</code> Activity:
<pre>
&#64;Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
- if ((keyCode == KeyEvent.KEYCODE_BACK) && webview.canGoBack()) {
- webview.goBack();
+ if ((keyCode == KeyEvent.KEYCODE_BACK) &amp;&amp; mWebView.canGoBack()) {
+ mWebView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
-}</pre>
- <p>The condition uses a {@link android.view.KeyEvent} to check
- whether the key pressed is the BACK button and whether the
- WebView is actually capable of navigating back (if it has a history). If both are
- <em>not</em> true, then we send the event up the chain (and the Activity will close).
- But if both <em>are</em> true, then we call <code>goBack()</code>,
- which will navigate back one step in the history. We then return true to indicate
- that we've handled the event.</p>
+}
+</pre>
+ <p>This {@link android.app.Activity#onKeyDown(int,KeyEvent)} callback method will be called
+ anytime a button is pressed while in the Activity. The condition inside uses the {@link
+ android.view.KeyEvent} to check whether the key pressed is the BACK button and whether the
+ {@link android.webkit.WebView} is actually capable of navigating back (if it has a history). If
+ both are true, then the {@link android.webkit.WebView#goBack()} method is called,
+ which will navigate back one step in the {@link android.webkit.WebView}
+ history.Returning <code>true</code> indicates that the event has been handled. If this condition
+ is not met, then the event is sent back to the system.</p>
</li>
+<li>Run the application again. You'll now be able to follow links and navigate back through the
+page history.</li>
</ol>
<p>When you open the application, it should look like this:</p>
<img src="images/hello-webview.png" width="150px" />
@@ -111,8 +129,3 @@ public boolean onKeyDown(int keyCode, KeyEvent event) {
<li>{@link android.webkit.WebViewClient}</li>
<li>{@link android.view.KeyEvent}</li>
</ul>
-
-
-
-
-
diff --git a/docs/html/resources/tutorials/views/images/android_focused.png b/docs/html/resources/tutorials/views/images/android_focused.png
new file mode 100644
index 0000000..f84d0fe
--- /dev/null
+++ b/docs/html/resources/tutorials/views/images/android_focused.png
Binary files differ
diff --git a/docs/html/resources/tutorials/views/images/android_normal.png b/docs/html/resources/tutorials/views/images/android_normal.png
new file mode 100644
index 0000000..94a7084
--- /dev/null
+++ b/docs/html/resources/tutorials/views/images/android_normal.png
Binary files differ
diff --git a/docs/html/resources/tutorials/views/images/android_pressed.png b/docs/html/resources/tutorials/views/images/android_pressed.png
new file mode 100644
index 0000000..fe81ff9
--- /dev/null
+++ b/docs/html/resources/tutorials/views/images/android_pressed.png
Binary files differ
diff --git a/docs/html/resources/tutorials/views/images/hello-autocomplete.png b/docs/html/resources/tutorials/views/images/hello-autocomplete.png
index e1fd80d..0b3e680 100755..100644
--- a/docs/html/resources/tutorials/views/images/hello-autocomplete.png
+++ b/docs/html/resources/tutorials/views/images/hello-autocomplete.png
Binary files differ
diff --git a/docs/html/resources/tutorials/views/images/hello-formstuff.png b/docs/html/resources/tutorials/views/images/hello-formstuff.png
index 3b4bf54..949319f 100755..100644
--- a/docs/html/resources/tutorials/views/images/hello-formstuff.png
+++ b/docs/html/resources/tutorials/views/images/hello-formstuff.png
Binary files differ
diff --git a/docs/html/resources/tutorials/views/images/hello-listview.png b/docs/html/resources/tutorials/views/images/hello-listview.png
index a1cf7aa..165b1ac 100755..100644
--- a/docs/html/resources/tutorials/views/images/hello-listview.png
+++ b/docs/html/resources/tutorials/views/images/hello-listview.png
Binary files differ
diff --git a/docs/html/resources/tutorials/views/images/hello-mapview.png b/docs/html/resources/tutorials/views/images/hello-mapview.png
index 0956760..6bd9740 100755..100644
--- a/docs/html/resources/tutorials/views/images/hello-mapview.png
+++ b/docs/html/resources/tutorials/views/images/hello-mapview.png
Binary files differ
diff --git a/docs/html/resources/tutorials/views/images/hello-tabwidget.png b/docs/html/resources/tutorials/views/images/hello-tabwidget.png
index 6a52356..6580c5b 100644
--- a/docs/html/resources/tutorials/views/images/hello-tabwidget.png
+++ b/docs/html/resources/tutorials/views/images/hello-tabwidget.png
Binary files differ
diff --git a/docs/html/resources/tutorials/views/images/hello-webview.png b/docs/html/resources/tutorials/views/images/hello-webview.png
index 283ce7d..248c6d4 100755..100644
--- a/docs/html/resources/tutorials/views/images/hello-webview.png
+++ b/docs/html/resources/tutorials/views/images/hello-webview.png
Binary files differ
diff --git a/docs/html/resources/tutorials/views/images/ic_tab_artists_grey.png b/docs/html/resources/tutorials/views/images/ic_tab_artists_grey.png
new file mode 100644
index 0000000..9baa30e
--- /dev/null
+++ b/docs/html/resources/tutorials/views/images/ic_tab_artists_grey.png
Binary files differ
diff --git a/docs/html/resources/tutorials/views/images/ic_tab_artists_white.png b/docs/html/resources/tutorials/views/images/ic_tab_artists_white.png
new file mode 100644
index 0000000..3b010d5
--- /dev/null
+++ b/docs/html/resources/tutorials/views/images/ic_tab_artists_white.png
Binary files differ
diff --git a/docs/html/resources/tutorials/views/index.jd b/docs/html/resources/tutorials/views/index.jd
index 2cb5d3a..6ea7683 100644
--- a/docs/html/resources/tutorials/views/index.jd
+++ b/docs/html/resources/tutorials/views/index.jd
@@ -3,116 +3,117 @@ page.title=Hello, Views
<style>
.view {float:left; margin:10px; font-size:120%; font-weight:bold;}
-.view img {border:1px solid black; margin:5px 0 0; padding:5px;}
+#jd-content .view img {border:1px solid black; margin:8px 0 0 0; padding:5px;}
</style>
-<p>This collection of "Hello World"-style tutorials is designed
-to get you quickly started with common Android Views and widgets. The aim is to let you copy and paste
-these kinds of boring bits so you can focus on developing the code that makes your Android application rock.
-Of course, we'll discuss some of the given code so that it all makes sense.</p>
+<p>This is a collection of "Hello World"-style tutorials designed
+to get you started quickly with common Android layouts and widgets.</p>
-<p>Note that a certain amount of knowledge is assumed for these tutorials. If you haven't
-completed the <a href="{@docRoot}resources/tutorials/hello-world.html">Hello, World</a> tutorial,
-please do so&mdash;it will teach you many things you should know about basic
-Android development and Eclipse features. More specifically, you should know:</p>
+<p>A certain amount of knowledge is assumed for these tutorials. Before you start,
+you should have completed the <a href="{@docRoot}resources/tutorials/hello-world.html">Hello,
+World</a> tutorial&mdash;it will teach you several things about basic
+Android development. More specifically, you should know:</p>
<ul>
- <li>How to create a new Android project.</li>
- <li>The basic structure of an Android project (resource files, layout files, etc.).</li>
- <li>The essential components of an {@link android.app.Activity}.</li>
- <li>How to build and run a project.</li>
+ <li>How to create an Android project and run it</li>
+ <li>The basic structure of an Android project (resource files, layout files, etc.)</li>
+ <li>The basic components of an {@link android.app.Activity}</li>
</ul>
-<p>Please, also notice that, in order to make these tutorials simple, some may
-not convey the better Android coding practices. In particular, many of them
-use hard-coded strings in the layout files&mdash;the better practice is to reference strings from
-your strings.xml file.</p>
-<p>With this knowledge, you're ready to begin, so take your pick.</p>
-<div>
+<p class="note"><strong>Note:</strong> In order to make these tutorials as simple as possible,
+some code may not conform to best practices for coding Android applications. In particular,
+hard-coded strings are used in places, when the better practice is to reference strings from a
+<code>res/values/strings.xml</code> resource file.</p>
+
+<p class="note"><strong>Tip:</strong> After you have pasted sample code into an Eclipse project,
+press <strong>Ctrl (or Cmd) + Shift + O</strong> to import the required packages.</p>
+
+<h2>Layouts</h2>
<div class="view">
-<a href="hello-linearlayout.html">LinearLayout</a><br/>
-<a href="hello-linearlayout.html"><img src="images/hello-linearlayout.png" height="285" width="200" /></a>
+<a href="hello-linearlayout.html">Linear Layout</a><br/>
+<a href="hello-linearlayout.html"><img src="images/hello-linearlayout.png" height="285" width="200"
+/></a>
</div>
+
<div class="view">
-<a href="hello-relativelayout.html">RelativeLayout</a><br/>
-<a href="hello-relativelayout.html"><img src="images/hello-relativelayout.png" height="285" width="200" /></a>
+<a href="hello-relativelayout.html">Relative Layout</a><br/>
+<a href="hello-relativelayout.html"><img src="images/hello-relativelayout.png" height="285"
+width="200" /></a>
</div>
+
<div class="view">
-<a href="hello-tablelayout.html">TableLayout</a><br/>
-<a href="hello-tablelayout.html"><img src="images/hello-tablelayout.png" height="285" width="200" /></a>
+<a href="hello-tablelayout.html">Table Layout</a><br/>
+<a href="hello-tablelayout.html"><img src="images/hello-tablelayout.png" height="285" width="200"
+/></a>
</div>
<div class="view">
-<a href="hello-datepicker.html">DatePicker</a><br/>
-<a href="hello-datepicker.html"><img src="images/hello-datepicker.png" height="285" width="200" /></a>
+<a href="hello-gridview.html">Grid View</a><br/>
+<a href="hello-gridview.html"><img src="images/hello-gridview.png" height="285" width="200" /></a>
</div>
<div class="view">
-<a href="hello-timepicker.html">TimePicker</a><br/>
-<a href="hello-timepicker.html"><img src="images/hello-timepicker.png" height="285" width="200" /></a>
+<a href="hello-tabwidget.html">Tab Layout</a><br/>
+<a href="hello-tabwidget.html"><img src="images/hello-tabwidget.png" height="285" width="200" /></a>
</div>
+
<div class="view">
-<a href="hello-formstuff.html">Form Stuff</a><br/>
-<a href="hello-formstuff.html"><img src="images/hello-formstuff.png" height="285" width="200" /></a>
+<a href="hello-listview.html">List View</a><br/>
+<a href="hello-listview.html"><img src="images/hello-listview.png" height="285" width="200" /></a>
</div>
+
+<p style="clear:left">&nbsp;</p>
+
+<h2>Widgets &amp; Other Views</h2>
+
<div class="view">
-<a href="hello-spinner.html">Spinner</a><br/>
-<a href="hello-spinner.html"><img src="images/hello-spinner.png" height="285" width="200" /></a>
+<a href="hello-datepicker.html">Date Picker</a><br/>
+<a href="hello-datepicker.html"><img src="images/hello-datepicker.png" height="285" width="200"
+/></a>
</div>
<div class="view">
-<a href="hello-autocomplete.html">AutoComplete</a><br/>
-<a href="hello-autocomplete.html"><img src="images/hello-autocomplete.png" height="285" width="200" /></a>
+<a href="hello-timepicker.html">Time Picker</a><br/>
+<a href="hello-timepicker.html"><img src="images/hello-timepicker.png" height="285" width="200"
+/></a>
</div>
+
<div class="view">
-<a href="hello-listview.html">ListView</a><br/>
-<a href="hello-listview.html"><img src="images/hello-listview.png" height="285" width="200" /></a>
+<a href="hello-formstuff.html">Form Stuff</a><br/>
+<a href="hello-formstuff.html"><img src="images/hello-formstuff.png" height="285" width="200" /></a>
</div>
+
<div class="view">
-<a href="hello-gridview.html">GridView</a><br/>
-<a href="hello-gridview.html"><img src="images/hello-gridview.png" height="285" width="200" /></a>
+<a href="hello-spinner.html">Spinner</a><br/>
+<a href="hello-spinner.html"><img src="images/hello-spinner.png" height="285" width="200" /></a>
</div>
<div class="view">
-<a href="hello-gallery.html">Gallery</a><br/>
-<a href="hello-gallery.html"><img src="images/hello-gallery.png" height="285" width="200" /></a>
+<a href="hello-autocomplete.html">Auto Complete</a><br/>
+<a href="hello-autocomplete.html"><img src="images/hello-autocomplete.png" height="285" width="200"
+/></a>
</div>
<div class="view">
-<a href="hello-tabwidget.html">TabWidget</a><br/>
-<a href="hello-tabwidget.html"><img src="images/hello-tabwidget.png" height="285" width="200" /></a>
+<a href="hello-gallery.html">Gallery</a><br/>
+<a href="hello-gallery.html"><img src="images/hello-gallery.png" height="285" width="200" /></a>
</div>
<div class="view">
-<a href="hello-mapview.html">MapView</a><br/>
+<a href="hello-mapview.html">Google Map View</a><br/>
<a href="hello-mapview.html"><img src="images/hello-mapview.png" height="285" width="200" /></a>
</div>
<div class="view">
-<a href="hello-webview.html">WebView</a><br/>
+<a href="hello-webview.html">Web View</a><br/>
<a href="hello-webview.html"><img src="images/hello-webview.png" height="285" width="200" /></a>
</div>
-<!--
-TODO
-
-<div class="view">
-<a href="hello-popupwindow.html">PopupWindow<br/>
-<img src="images/hello-popupwindow.png" height="285" width="200" /></a>
-</div>
-<div class="view">
-<a href="hello-tabhost.html">TabHost / TabWidget<br/>
-<img src="images/hello-tabhost.png" height="285" width="200" /></a>
-</div>
-ProgressBar; RatingBar; FrameLayout
-
--->
<p class="note" style="clear:left">
-There are plenty more Views and widgets available. See the {@link android.view.View} class
+There are plenty more layouts and widgets available. See the {@link android.view.View} class
for more on View layouts, and the {@link android.widget widget package}
for more useful widgets. And for more raw code samples, visit the
-<a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/index.html">Api Demos</a>.
-These can also be found offline, in <code>/&lt;sdk&gt;/samples/ApiDemos</code>.</p>
-</div>
+<a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/index.html">Api
+Demos</a>.</p>
diff --git a/docs/html/shareables/sample_images.zip b/docs/html/shareables/sample_images.zip
new file mode 100644
index 0000000..007a68a
--- /dev/null
+++ b/docs/html/shareables/sample_images.zip
Binary files differ