blob: 4385d1304b7f6767299e4f124f8083ae5b250800 [file] [log] [blame]
page.title=Starting Another Activity
parent.title=Building Your First App
parent.link=index.html
trainingnavtop=true
page.tags=intents
helpoutsWidget=true
@jd:body
<!-- This is the training bar -->
<div id="tb-wrapper">
<div id="tb">
<h2>This lesson teaches you to</h2>
<ol>
<li><a href="#RespondToButton">Respond to the Send Button</a></li>
<li><a href="#BuildIntent">Build an Intent</a></li>
<li><a href="#CreateActivity">Create the Second Activity</a></li>
<li><a href="#DisplayMessage">Display the Message</a></li>
</ol>
</div>
</div>
<p>After completing the <a href="building-ui.html">previous lesson</a>, you have an app that
shows an activity (a single screen) with a text field and a button. In this lesson, youll add some
code to <code>MainActivity</code> that
starts a new activity when the user clicks the Send button.</p>
<h2 id="RespondToButton">Respond to the Send Button</h2>
<ol>
<li>In the file <b>res > layout > activity_main.xml</b>, add the
<a href="{@docRoot}reference/android/view/View.html#attr_android:onClick">{@code android:onClick}</a>
attribute to the {@link android.widget.Button &lt;Button&gt;} element as
shown below:
<pre>&lt;Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_send"
<b>android:onClick="sendMessage"</b> />
</pre>
<p>This attribute tells the system to call the <code>sendMessage()</code>
method in your activity whenever a user clicks on the button.</p>
</li>
<li>In the file <b>java > com.example.myfirstapp > MainActivity.java</b>,
add the <code>sendMessage()</code> method stub as shown below:
<pre>public class MainActivity extends AppCompatActivity {
&#64;Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
<b>/** Called when the user clicks the Send button */
public void sendMessage(View view) {
// Do something in response to button
}</b>
}</pre>
<p>In order for the system to match this method to the method name given to <a
href="{@docRoot}reference/android/view/View.html#attr_android:onClick">{@code android:onClick}</a>,
the signature must be exactly as shown. Specifically, the method must:</p>
<ul>
<li>Be public</li>
<li>Have a void return value</li>
<li>Have a {@link android.view.View} as the only parameter (this will be the {@link
android.view.View} that was clicked)</li>
</ul>
</li>
</ol>
<p>Next, youll fill in this method to read the contents of the text field and deliver that text to
another activity.</p>
<h2 id="BuildIntent">Build an Intent</h2>
<p>An {@link android.content.Intent} is an object that provides runtime binding
between separate components (such as two activities). The
{@link android.content.Intent} represents an apps "intent to do something."
You can use intents for a wide variety of tasks, but in this lesson, your intent
starts another activity.</p>
<p>In <code>MainActivity.java</code>, add the code shown below to
<code>sendMessage()</code>:</p>
<pre>public class MainActivity extends AppCompatActivity {
<b>public final static String EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE";</b>
&#64;Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/** Called when the user clicks the Send button */
public void sendMessage(View view) {
<b>Intent intent = new Intent(this, DisplayMessageActivity.class);
EditText editText = (EditText) findViewById(R.id.edit_message);
String message = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
startActivity(intent);</b>
}
}</pre>
<p>Android Studio will display <b>Cannot
resolve symbol</b> errors because this code references classes that are not
imported. You can solve some of these with Android Studio's "import class"
functionality by pressing Alt + Enter (or Option + Return on Mac).
Your imports should end up as the following:</p>
<pre>
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
</pre>
<p>An error remains for <code>DisplayMessageActivity</code>, but that's okay;
you'll fix that in the next section.
<p>There’s a lot going on in <code>sendMessage()</code>, so let’s explain
what's going on.</p>
<p>The {@link android.content.Intent} constructor takes two parameters:</p>
<ul>
<li>A {@link android.content.Context} as its first parameter ({@code this}
is used because the {@link android.app.Activity} class is a subclass of
{@link android.content.Context})
<li>The {@link java.lang.Class} of the app component to which the system
should deliver the {@link android.content.Intent} (in this case, the
activity that should be started).
<p class="note"><strong>Note:</strong> The reference to
<code>DisplayMessageActivity</code> will raise an error in Android Studio
because the class doesnt exist yet. Ignore the error for now; youll
create the class soon.</p>
</ul>
<p>The {@link android.content.Intent#putExtra(String, String) putExtra()}
method adds the <code>EditText</code>'s value to the intent. An <code>Intent</code>
can carry data types as key-value pairs called <em>extras</em>. Your key is a
public constant <code>EXTRA_MESSAGE</code> because the next
activity uses the key to retrive the text value. It's a good practice to
define keys for intent extras using your app's package name as a prefix. This
ensures the keys are unique, in case your app interacts with other apps.</p>
<p>The {@link android.app.Activity#startActivity(Intent) startActivity()}
method starts an instance of the <code>DisplayMessageActivity</code> specified
by the {@link android.content.Intent}. Now you need to create the class.</p>
<h2 id="CreateActivity">Create the Second Activity</h2>
<ol>
<li>In the <b>Project</b> window, right-click the <b>app</b> folder and select
<strong>New > Activity > Empty Activity</strong>.</li>
<li>In the <strong>Configure Activity</strong> window, enter
"DisplayMessageActivity" for <strong>Activity Name</strong> and click
<strong>Finish</strong>
</li>
</ol>
<p>Android Studio automatically does three things:</p>
<ul>
<li>Creates the class <code>DisplayMessageActivity.java</code> with an
implementation of the required {@link android.app.Activity#onCreate(Bundle) onCreate()}
method.</li>
<li>Creates the corresponding layout file <code>activity_display_message.xml</code>
</li>
<li>Adds the required
<a href="{@docRoot}guide/topics/manifest/activity-element.html"
><code>&lt;activity&gt;</code></a>
element in <code>AndroidManifest.xml</code>.
</ul>
<p>If you run the app and click the Send button on the first activity, the
second activity starts but is empty. This is because the second activity uses
the default empty layout provided by the template.</p>
<h2 id="DisplayMessage">Display the Message</h2>
<p>Now you will modify the second activity to display the message that was passed
by the first activity.</p>
<ol>
<li>In {@code DisplayMessageActivity.java}, add the following code to the
<code>onCreate()</code> method:
<pre>&#64;Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_message);
Intent intent = getIntent();
String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
TextView textView = new TextView(this);
textView.setTextSize(40);
textView.setText(message);
ViewGroup layout = (ViewGroup) findViewById(R.id.activity_display_message);
layout.addView(textView);
}</pre>
</li>
<li>Press Alt + Enter (or Option + Return on Mac) to import missing classes.
Your imports should end up as the following:
<pre>
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.ViewGroup;
import android.widget.TextView;
</pre>
</li>
</ol>
<p>Theres a lot going on here, so lets explain:</p>
<ol>
<li>The call {@link android.app.Activity#getIntent()} grabs the intent
that started the activity. Every {@link android.app.Activity} is invoked by an
{@link android.content.Intent}, regardless of how the user navigated there.
The call {@link android.content.Intent#getStringExtra(String) getStringExtra()}
retrieves the data from the first activity.</li>
<li>You programmatically create a {@link android.widget.TextView} and set
its size and message.
</li>
<li>You add the <code>TextView</code> to the layout identified by
{@code R.id.activity_display_message}. You cast the layout to
{@link android.view.ViewGroup} because it is the superclass of all layouts and
contains the {@link android.view.ViewGroup#addView(View) addView()}
method.</li>
</ol>
<p class="note"><strong>Note: </strong>The XML layout generated by previous
versions of Android Studio might not include the <code>android:id</code>
attribute. The call <code>findViewById()</code> will fail if the layout
does not have the <code>android:id</code> attribute. If this is the case,
open <code>activity_display_message.xml</code> and add the attribute
<code>android:id="@+id/activity_display_message"</code> to the layout element.
</p>
<p>You can now run the app. When it opens, type a message in the text field, and click
<strong>Send</strong>. The second activity replaces the first one on the screen, showing
the message you entered in the first activity.</p>
<p>That's it, you've built your first Android app!</p>
<p>To learn more, follow the link below to the next class.</p>