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 Bug:2338253
@@ -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>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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">
|
||||
</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>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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">
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Country" />
|
||||
|
||||
<AutoCompleteTextView android:id="@+id/edit"
|
||||
<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"/>
|
||||
</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>
|
||||
@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<String> adapter = new ArrayAdapter<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 <string-array<} resource in your project {@code res/values/strings.xml} file.
|
||||
For example:</p>
|
||||
<pre>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string-array name="countries_array">
|
||||
<item>Bahrain</item>
|
||||
<item>Bangladesh</item>
|
||||
<item>Barbados</item>
|
||||
<item>Belarus</item>
|
||||
<item>Belgium</item>
|
||||
<item>Belize</item>
|
||||
<item>Benin</item>
|
||||
</string-array>
|
||||
</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<String> adapter = new ArrayAdapter<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>
|
||||
|
||||
@@ -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>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<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=""/>
|
||||
<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"/>
|
||||
</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>
|
||||
<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 HelloDatePicker.java. Insert the following to the HelloDatePicker class:
|
||||
<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>
|
||||
|
||||
@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>—our own method (defined later) that will fill the TextView.</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>After the <code>onCreate()</code> method, add the <code>onCreateDialog()</code> callback method
|
||||
(which is called by <code>showDialog()</code>)
|
||||
<li>Add the <code>updateDisplay()</code> method:
|
||||
<pre>
|
||||
@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>
|
||||
</li>
|
||||
|
||||
<li>Following that, 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 run it.</li>
|
||||
<li>Now add the {@link android.app.Activity#onCreateDialog(int)} callback method to the {@code
|
||||
HelloDatePicker} class:
|
||||
<pre>
|
||||
@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>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>
|
||||
|
||||
@@ -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>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent" >
|
||||
|
||||
</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>
|
||||
|
||||
|
||||
<h2>ImageButton</h2>
|
||||
<p>A button with a custom image on it.
|
||||
We'll make it display a message when pressed.</p>
|
||||
<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:
|
||||
<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>
|
||||
<ImageButton
|
||||
android:id="@+id/android_button"
|
||||
android:layout_width="100dip"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/android" />
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.main);
|
||||
}
|
||||
</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>
|
||||
</li>
|
||||
<li>To make the button to actually do something, add the following
|
||||
code at the end of the <code>onCreate()</code> method:
|
||||
|
||||
|
||||
|
||||
<h2>Custom Button</h2>
|
||||
|
||||
<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>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>
|
||||
final ImageButton button = (ImageButton) findViewById(R.id.android_button);
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/android_pressed"
|
||||
android:state_pressed="true" />
|
||||
<item android:drawable="@drawable/android_focused"
|
||||
android:state_focused="true" />
|
||||
<item android:drawable="@drawable/android_normal" />
|
||||
</selector>
|
||||
</pre>
|
||||
<p>This defines a single drawable resource, which will change its image based on the current
|
||||
state of the button. The first <code><item></code> defines
|
||||
<code>android_pressed.png</code> as the image when the button is pressed (it's been
|
||||
activated); the second <code><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><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><item></code> elements is
|
||||
important. When this drawable is referenced, the <code><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>
|
||||
<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 do something when pressed, add the following
|
||||
code at the end of the {@link android.app.Activity#onCreate(Bundle) onCreate()} method:
|
||||
<pre>
|
||||
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>
|
||||
<EditText
|
||||
android:id="@+id/edittext"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
<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) &&
|
||||
(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>
|
||||
<CheckBox android:id="@+id/checkbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="check it out" />
|
||||
<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—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>
|
||||
<RadioGroup
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RadioButton android:id="@+id/radio_red"
|
||||
android:layout_width="wrap_content"
|
||||
<RadioGroup
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Red" />
|
||||
|
||||
<RadioButton android:id="@+id/radio_blue"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Blue" />
|
||||
|
||||
</RadioGroup>
|
||||
android:orientation="vertical">
|
||||
<RadioButton android:id="@+id/radio_red"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Red" />
|
||||
<RadioButton android:id="@+id/radio_blue"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Blue" />
|
||||
</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>
|
||||
<ToggleButton android:id="@+id/togglebutton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
<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>
|
||||
|
||||
|
||||
<p>If you've added all the form items above, your application should look something like this:</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>
|
||||
<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 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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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>
|
||||
@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—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>Create a new XML file in the <code>res/values/</code> directory named <code>attrs.xml</code>.
|
||||
Insert the following:
|
||||
<pre>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<declare-styleable name="HelloGallery">
|
||||
<attr name="android:galleryItemBackground" />
|
||||
</declare-styleable>
|
||||
</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><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>After the <code>onCreate()</code> method, add the <code>ImageAdapter</code> class:
|
||||
<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>
|
||||
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, in case you want to avoid stretching images that don't
|
||||
exactly match the ImageView dimensions.</p>
|
||||
<p>See {@link android.widget.ImageView.ScaleType} for other image scaling options.</p>
|
||||
</li>
|
||||
|
||||
<li>Now run it.</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>
|
||||
|
||||
|
||||
|
||||
@@ -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>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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<?> 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—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—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—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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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">
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_weight="1">
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_weight="1">
|
||||
<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"/>
|
||||
<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"/>
|
||||
<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"/>
|
||||
<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"/>
|
||||
</LinearLayout>
|
||||
|
||||
<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"/>
|
||||
|
||||
<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"/>
|
||||
|
||||
<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"/>
|
||||
|
||||
<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"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_weight="1">
|
||||
|
||||
<TextView
|
||||
android:text="row one"
|
||||
android:textSize="15pt"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
<TextView
|
||||
android:text="row two"
|
||||
android:textSize="15pt"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
<TextView
|
||||
android:text="row three"
|
||||
android:textSize="15pt"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
<TextView
|
||||
android:text="row four"
|
||||
android:textSize="15pt"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_weight="1">
|
||||
<TextView
|
||||
android:text="row one"
|
||||
android:textSize="15pt"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"/>
|
||||
<TextView
|
||||
android:text="row two"
|
||||
android:textSize="15pt"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"/>
|
||||
<TextView
|
||||
android:text="row three"
|
||||
android:textSize="15pt"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"/>
|
||||
<TextView
|
||||
android:text="row four"
|
||||
android:textSize="15pt"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"/>
|
||||
</LinearLayout>
|
||||
|
||||
</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—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 — <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>
|
||||
|
||||
|
||||
|
||||
@@ -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>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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" >
|
||||
</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>
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setListAdapter(new ArrayAdapter<String>(this,
|
||||
android.R.layout.simple_list_item_1, COUNTRIES));
|
||||
getListView().setTextFilterEnabled(true);
|
||||
|
||||
setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, COUNTRIES));
|
||||
|
||||
ListView lv = getListView();
|
||||
lv.setTextFilterEnabled(true);
|
||||
|
||||
lv.setOnItemClickListener(new OnItemClickListener() {
|
||||
public void onItemClick(AdapterView<?> 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 <string-array>}
|
||||
resource in your project {@code res/values/strings.xml} file. For example:</p>
|
||||
<pre>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string-array name="countries_array">
|
||||
<item>Bahrain</item>
|
||||
<item>Bangladesh</item>
|
||||
<item>Barbados</item>
|
||||
<item>Belarus</item>
|
||||
<item>Belgium</item>
|
||||
<item>Belize</item>
|
||||
<item>Benin</item>
|
||||
</string-array>
|
||||
</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<String>(this, R.layout.list_item, countries));
|
||||
</pre>
|
||||
|
||||
<h3>References</h3>
|
||||
<ul>
|
||||
<li>{@link android.widget.ListView}</li>
|
||||
|
||||
@@ -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>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 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>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>Start a new project named <em>HelloGoogleMaps</em>.</li>
|
||||
|
||||
<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><application></code> element:
|
||||
<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><application></code> element:
|
||||
<pre><uses-library android:name="com.google.android.maps" /></pre>
|
||||
</li>
|
||||
|
||||
<pre><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><manifest></code> element:
|
||||
<pre><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>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><manifest></code> element:
|
||||
<pre><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>
|
||||
<activity android:name=".HelloGoogleMaps" android:label="@string/app_name"
|
||||
<strong>android:theme="@android:style/Theme.NoTitleBar"</strong>>
|
||||
</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>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/mainlayout"
|
||||
android:orientation="vertical"
|
||||
<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" >
|
||||
|
||||
<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>"
|
||||
/>
|
||||
|
||||
</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>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>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>
|
||||
<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 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>
|
||||
<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 HelloMapView extends MapActivity {</pre>
|
||||
<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>The <code>isRouteDisplayed()</code> method is required, so add it inside the class:
|
||||
<li>Inside every {@code MapActivity}, the <code>isRouteDisplayed()</code> method is required, so
|
||||
override this method:
|
||||
<pre>
|
||||
@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>
|
||||
<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:
|
||||
@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;
|
||||
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::
|
||||
<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.
|
||||
<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 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>
|
||||
<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 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:
|
||||
<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<OverlayItem> mOverlays = new ArrayList<OverlayItem>();</pre></li>
|
||||
<pre>private ArrayList<OverlayItem> mOverlays = new ArrayList<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>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>
|
||||
@Override
|
||||
protected OverlayItem createItem(int i) {
|
||||
return mOverlays.get(i);
|
||||
}
|
||||
</pre></li>
|
||||
</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:
|
||||
<li>You must also override the <code>size()</code> method to return the current number of
|
||||
items in the ArrayList:
|
||||
<pre>
|
||||
@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>Then override the {@code onTap(int)} callback method, which will handle the event
|
||||
when an item is tapped by the user:</p>
|
||||
<pre>
|
||||
@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>
|
||||
|
||||
<pre>return mOverlays.size();</pre></li>
|
||||
</ol>
|
||||
|
||||
<p>You're now done with the <code>HelloItemizedOverlay</code> class and can start using it
|
||||
to add items on the map.</p>
|
||||
|
||||
<p>That's it for the HelloItemizedOverlay class. We're now ready to use it.</p>
|
||||
|
||||
<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>
|
||||
<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" />
|
||||
<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>Now we're ready to work in the HelloMapView:</p>
|
||||
|
||||
<ol>
|
||||
<li>First we need some more types. Add the following at the top of the HelloMapView class:
|
||||
<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>At the end of your existing {@code onCreate()} method, instantiate :
|
||||
|
||||
<pre>
|
||||
List<Overlay> mapOverlays;
|
||||
Drawable drawable;
|
||||
HelloItemizedOverlay itemizedOverlay;</pre></li>
|
||||
List<Overlay> mapOverlays = mapView.getOverlays();
|
||||
Drawable drawable = this.getResources().getDrawable(R.drawable.androidmarker);
|
||||
HelloItemizedOverlay itemizedoverlay = new HelloItemizedOverlay(drawable);</pre>
|
||||
|
||||
<li>Now pick up where we left off in the <code>onCreate()</code> method. Instantiate the
|
||||
new fields:
|
||||
|
||||
<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:
|
||||
<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>
|
||||
OverlayItem overlayitem = new OverlayItem(point, "Hola, Mundo!", "I'm in Mexico City!");
|
||||
</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>
|
||||
|
||||
<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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/label"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Type here:"/>
|
||||
|
||||
<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"/>
|
||||
|
||||
<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" />
|
||||
|
||||
<Button
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_toLeftOf="@id/ok"
|
||||
android:layout_alignTop="@id/ok"
|
||||
android:text="Cancel" />
|
||||
|
||||
</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 — <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>
|
||||
|
||||
@@ -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>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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">
|
||||
|
||||
<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"
|
||||
/>
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/spinner"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawSelectorOnTop="true"
|
||||
android:prompt="@string/planet_prompt"
|
||||
/>
|
||||
|
||||
</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>
|
||||
<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>Open the strings.xml file in res/values/ and add the following <code><string></code>
|
||||
element inside the <code><resources></code> element:
|
||||
<pre>
|
||||
<string name="planet_prompt">Choose a planet</string>
|
||||
</pre>
|
||||
</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>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<string-array name="planets">
|
||||
<string name="planet_prompt">Choose a planet</string>
|
||||
<string-array name="planets_array">
|
||||
<item>Mercury</item>
|
||||
<item>Venus</item>
|
||||
<item>Earth</item>
|
||||
@@ -63,35 +56,85 @@ element inside the <code><resources></code> element:
|
||||
<item>Uranus</item>
|
||||
<item>Neptune</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
||||
</pre>
|
||||
<p>This is the list of items (planets) that the user can select from in the Spinner widget.</p>
|
||||
<p>The {@code <string>} element defines the title string referenced by the {@link
|
||||
android.widget.TextView} and {@link android.widget.Spinner} in the layout above. The {@code
|
||||
<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>
|
||||
@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<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>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—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>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 run it.</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<?> 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>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>Run the application.</li>
|
||||
</ol>
|
||||
<p>It should look like this:</p>
|
||||
<img src="images/hello-spinner.png" width="150px" />
|
||||
|
||||
@@ -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>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
@@ -89,21 +88,28 @@ will lay child View elements into rows and columns.</p>
|
||||
</TableRow>
|
||||
</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><table></code> element; {@link android.widget.TableRow} is like
|
||||
a <code>><tr>></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 — <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" />
|
||||
|
||||
@@ -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>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- When selected, use grey -->
|
||||
<item android:drawable="@drawable/ic_tab_artists_grey"
|
||||
android:state_selected="true" />
|
||||
<!-- When not selected, use white-->
|
||||
<item android:drawable="@drawable/ic_tab_artists_white" />
|
||||
</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>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
@@ -18,7 +76,8 @@ tabs to navigate between different views.</p>
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
android:layout_height="fill_parent"
|
||||
android:padding="5dp">
|
||||
<TabWidget
|
||||
android:id="@android:id/tabs"
|
||||
android:layout_width="fill_parent"
|
||||
@@ -26,94 +85,111 @@ tabs to navigate between different views.</p>
|
||||
<FrameLayout
|
||||
android:id="@android:id/tabcontent"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
<TextView
|
||||
android:id="@+id/textview1"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:text="this is a tab" />
|
||||
<TextView
|
||||
android:id="@+id/textview2"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:text="this is another tab" />
|
||||
<TextView
|
||||
android:id="@+id/textview3"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:text="this is a third tab" />
|
||||
</FrameLayout>
|
||||
android:layout_height="fill_parent"
|
||||
android;padding="5dp" />
|
||||
</LinearLayout>
|
||||
</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 — 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><application></code> tag. It should end up like this:
|
||||
<pre>
|
||||
<application android:icon="@drawable/icon" android:theme="@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><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><activity></code> tag should look like this:
|
||||
<pre>
|
||||
<activity android:name=".HelloTabWidget" android:label="@string/app_name"
|
||||
android:theme="@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>
|
||||
|
||||
@@ -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>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView android:id="@+id/timeDisplay"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text=""/>
|
||||
|
||||
<Button android:id="@+id/pickTime"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Change the time"/>
|
||||
|
||||
</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>
|
||||
<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>
|
||||
|
||||
<li>Open HelloTimePicker.java. Insert the following to the HelloTimePicker class:
|
||||
<li>Open <code>HelloTimePicker.java</code> and insert the following class members:
|
||||
<pre>
|
||||
private TextView mTimeDisplay;
|
||||
private Button mPickTime;
|
||||
private TextView mTimeDisplay;
|
||||
private Button mPickTime;
|
||||
|
||||
private int mHour;
|
||||
private int mMinute;
|
||||
private int mHour;
|
||||
private int mMinute;
|
||||
|
||||
static final int TIME_DIALOG_ID = 0;
|
||||
|
||||
@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();
|
||||
}
|
||||
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>—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>
|
||||
@Override
|
||||
protected Dialog onCreateDialog(int id) {
|
||||
switch (id) {
|
||||
case TIME_DIALOG_ID:
|
||||
return new TimePickerDialog(this,
|
||||
mTimeSetListener, mHour, mMinute, false);
|
||||
@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—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>
|
||||
</li>
|
||||
<li>Finally, add the <code>pad()</code> method that we called from the <code>updateDisplay()</code>:
|
||||
<pre>
|
||||
private static String pad(int c) {
|
||||
if (c >= 10)
|
||||
return String.valueOf(c);
|
||||
else
|
||||
return "0" + String.valueOf(c);
|
||||
}
|
||||
</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>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>Now run it.</li>
|
||||
<li>Add the {@link android.app.Activity#onCreateDialog(int)} callback method:
|
||||
<pre>
|
||||
@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 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>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>
|
||||
|
||||
@@ -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>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<WebView
|
||||
android:id="@+id/webview"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
</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>
|
||||
<pre>
|
||||
webview = (WebView) findViewById(R.id.webview);
|
||||
webview.getSettings().setJavaScriptEnabled(true);
|
||||
webview.loadUrl("http://www.google.com");
|
||||
<WebView
|
||||
android:id="@+id/webview"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
/>
|
||||
</pre>
|
||||
</li>
|
||||
|
||||
<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>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>
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.main);
|
||||
|
||||
<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><manifest></code> element:
|
||||
mWebView = (WebView) findViewById(R.id.webview);
|
||||
mWebView.getSettings().setJavaScriptEnabled(true);
|
||||
mWebView.loadUrl("http://www.google.com");
|
||||
}
|
||||
</pre>
|
||||
<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>
|
||||
|
||||
<pre><uses-permission android:name="android.permission.INTERNET" /></pre></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><manifest></code> element:
|
||||
|
||||
<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>
|
||||
<pre><uses-permission android:name="android.permission.INTERNET" /></pre></li>
|
||||
|
||||
<hr/>
|
||||
<li>While you're in the manifest, give some more space for web pages by removing the title
|
||||
bar, with the "NoTitleBar" theme:
|
||||
<pre>
|
||||
<activity android:name=".HelloGoogleMaps" android:label="@string/app_name"
|
||||
<strong>android:theme="@android:style/Theme.NoTitleBar"</strong>>
|
||||
</pre>
|
||||
</li>
|
||||
|
||||
<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>
|
||||
<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>
|
||||
|
||||
<ol>
|
||||
<li>In the HelloAndroid Activity, add this nested private class:
|
||||
<li>In the <code>HelloAndroid</code> Activity, add this nested class:
|
||||
<pre>
|
||||
private class HelloWebViewClient extends WebViewClient {
|
||||
@Override
|
||||
@@ -65,42 +74,51 @@ private class HelloWebViewClient extends WebViewClient {
|
||||
view.loadUrl(url);
|
||||
return true;
|
||||
}
|
||||
}</pre></li>
|
||||
}
|
||||
</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>
|
||||
|
||||
<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—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>
|
||||
<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>
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
if ((keyCode == KeyEvent.KEYCODE_BACK) && webview.canGoBack()) {
|
||||
webview.goBack();
|
||||
if ((keyCode == KeyEvent.KEYCODE_BACK) && 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>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
docs/html/resources/tutorials/views/images/android_focused.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
docs/html/resources/tutorials/views/images/android_normal.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
docs/html/resources/tutorials/views/images/android_pressed.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
docs/html/resources/tutorials/views/images/hello-autocomplete.png
Executable file → Normal file
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 17 KiB |
BIN
docs/html/resources/tutorials/views/images/hello-formstuff.png
Executable file → Normal file
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 23 KiB |
BIN
docs/html/resources/tutorials/views/images/hello-listview.png
Executable file → Normal file
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 26 KiB |
BIN
docs/html/resources/tutorials/views/images/hello-mapview.png
Executable file → Normal file
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 10 KiB |
BIN
docs/html/resources/tutorials/views/images/hello-webview.png
Executable file → Normal file
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 791 B |
|
After Width: | Height: | Size: 1.1 KiB |
@@ -3,74 +3,95 @@ 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—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—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—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>
|
||||
</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>
|
||||
</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-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-datepicker.html">DatePicker</a><br/>
|
||||
<a href="hello-datepicker.html"><img src="images/hello-datepicker.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-timepicker.html">TimePicker</a><br/>
|
||||
<a href="hello-timepicker.html"><img src="images/hello-timepicker.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-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-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-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"> </p>
|
||||
|
||||
<h2>Widgets & Other Views</h2>
|
||||
|
||||
<div class="view">
|
||||
<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-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-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-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-autocomplete.html">AutoComplete</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-listview.html">ListView</a><br/>
|
||||
<a href="hello-listview.html"><img src="images/hello-listview.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-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">
|
||||
@@ -79,40 +100,20 @@ your strings.xml file.</p>
|
||||
</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>
|
||||
</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>/<sdk>/samples/ApiDemos</code>.</p>
|
||||
</div>
|
||||
<a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/index.html">Api
|
||||
Demos</a>.</p>
|
||||
|
||||
|
||||