| page.title=Form Stuff |
| parent.title=Hello, Views |
| parent.link=index.html |
| @jd:body |
| |
| <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 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 this {@link |
| android.widget.LinearLayout}.</p> |
| </li> |
| </ol> |
| <p>Each section below also assumes that your <code>HelloFormStuff</code> Activity has the following |
| default implementation of the {@link android.app.Activity#onCreate(Bundle) onCreate()} method:</p> |
| <pre> |
| public void onCreate(Bundle savedInstanceState) { |
| super.onCreate(savedInstanceState); |
| setContentView(R.layout.main); |
| } |
| </pre> |
| |
| <p>Now select which kind of form widget you'd like to create:</p> |
| <ul> |
| <li><a href="#CustomButton">Custom Button</a></li> |
| <li><a href="#EditText">Edit Text</a></li> |
| <li><a href="#Checkbox">Checkbox</a></li> |
| <li><a href="#RadioButtons">Radio Buttons</a></li> |
| <li><a href="#ToggleButton">Toggle Button</a></li> |
| <li><a href="#RatingBar">Rating Bar</a></li> |
| </ul> |
| |
| |
| |
| <h2 id="CustomButton">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> |
| <?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" |
| android:onClick="onButtonClicked"/> |
| </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 |
| applied by the system with the drawable created above, which changes its image based on |
| the button state.</p> |
| <p>The attribute <code>android:onClick</code> specifies the name of a method in your activity |
| that the system should call when the user clicks the button. You'll create that method next.</p> |
| </li> |
| |
| <li>To make the button do something when pressed, add the following |
| method inside your {@link android.app.Activity} class: |
| <pre> |
| public void onButtonClicked(View v) { |
| // Do something when the button is clicked |
| Toast.makeText(HelloFormStuff.this, "Button clicked", Toast.LENGTH_SHORT).show(); |
| } |
| </pre> |
| <p>When you specify this kind of method, which is used in your layout file with the {@code |
| android:onClick} attribute, the method must be <code>public</code>, have a <code>void</code> return |
| value, and accept a single {@code android.view.View} parameter. When the system calls this method, |
| it passes the {@code android.view.View} that was clicked.</p> |
| </li> |
| <li>Now run the application.</li> |
| </ol> |
| |
| |
| |
| <h2 id="EditText">Edit Text</h2> |
| |
| <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 <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"/> |
| </pre> |
| </li> |
| <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 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; |
| } |
| return false; |
| } |
| }); |
| </pre> |
| <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 id="Checkbox">Checkbox</h2> |
| |
| <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 <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" |
| android:onClick="onCheckboxClicked"/> |
| </pre> |
| <p>The attribute <code>android:onClick</code> specifies the name of a method in your activity |
| that the system should call when the user clicks the check box. You'll create that method next.</p> |
| </li> |
| <li>To do something when the state is changed, add the following method inside your {@link |
| android.app.Activity} class:</p> |
| |
| <pre> |
| public void onCheckboxClicked(View v) { |
| // 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(); |
| } |
| } |
| </pre> |
| |
| <p>When you specify this kind of method, which is used in your layout file with the {@code |
| android:onClick} |
| attribute, the method must be <code>public</code>, have a <code>void</code> return value, and |
| accept a single {@code android.view.View} parameter. When the system calls this method, it |
| passes the {@code android.view.View} that was clicked. In this example, the {@code |
| android.view.View} is cast to a {@link android.widget.CheckBox} to determine whether the widget |
| has been checked or unchecked. The {@link android.widget.CheckBox} widget |
| 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 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 id="RadioButtons">Radio Buttons</h2> |
| |
| <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 <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" |
| android:layout_height="wrap_content" |
| android:text="Red" |
| android:onClick="onRadioButtonClicked"/> |
| <RadioButton android:id="@+id/radio_blue" |
| android:layout_width="wrap_content" |
| android:layout_height="wrap_content" |
| android:text="Blue" |
| android:onClick="onRadioButtonClicked"/> |
| </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> |
| <p>The attribute <code>android:onClick</code> specifies the name of a method in your activity |
| that the system should call when the user clicks the radio button. You'll create that method |
| next.</p> |
| </li> |
| |
| <li>To do something when each {@link android.widget.RadioButton} is selected, add the following |
| method inside your {@link android.app.Activity} class:</p> |
| |
| <pre> |
| public void onRadioButtonClicked(View v) { |
| // Perform action on clicks |
| RadioButton rb = (RadioButton) v; |
| Toast.makeText(HelloFormStuff.this, rb.getText(), Toast.LENGTH_SHORT).show(); |
| } |
| </pre> |
| |
| <p>When you specify this kind of method, which is used in your layout file with the {@code |
| android:onClick} |
| attribute, the method must be <code>public</code>, have a <code>void</code> return value, and |
| accept a single {@code android.view.View} parameter. When the system calls this method, it |
| passes the {@code android.view.View} that was clicked.</p> |
| <p>Because each {@link android.widget.RadioButton} widget is grouped into a {@link |
| android.widget.RadioGroup}, each widget handles its own state changes when a new button is |
| selected.</p> |
| </li> |
| <li>Run the application.</li> |
| </ol> |
| |
| <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 id="ToggleButton">Toggle Button</h2> |
| |
| <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 <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" |
| android:textOn="Vibrate on" |
| android:textOff="Vibrate off" |
| android:onClick="onToggleClicked"/> |
| </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> |
| <p>The attribute <code>android:onClick</code> specifies the name of a method in your activity |
| that the system should call when the user clicks the button. You'll create that method next.</p> |
| </li> |
| <li>To do something when the user clicks the button, add the following |
| method inside your {@link android.app.Activity} class:</p> |
| |
| <pre> |
| public void onToggleClicked(View v) { |
| // Perform action on clicks |
| if (((ToggleButton) v).isChecked()) { |
| Toast.makeText(HelloFormStuff.this, "Toggle on", Toast.LENGTH_SHORT).show(); |
| } else { |
| Toast.makeText(HelloFormStuff.this, "Toggle off", Toast.LENGTH_SHORT).show(); |
| } |
| } |
| </pre> |
| |
| <p>When you specify this kind of method, which is used in your layout file with the {@code |
| android:onClick} |
| attribute, the method must be <code>public</code>, have a <code>void</code> return value, and |
| accept a single {@code android.view.View} parameter. When the system calls this method, it |
| passes the {@code android.view.View} that was clicked.</p> |
| <p>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> 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 id="RatingBar">Rating Bar</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> |
| <ul> |
| <li>{@link android.widget.ImageButton}</li> |
| <li>{@link android.widget.EditText}</li> |
| <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> |
| |