原文地址:http://developer.android.com/training/basics/firstapp/starting-activity.html
------------------------------------------------------------------------------------------
After completing the previous lesson, you have an app that shows an activity (a single screen) with a text field and a button. In this lesson, you’ll add some code to MainActivity
that starts a new activity when the user clicks the Send button.
在完成上一节课后,你已经有了一个显示一个activity(单独一个屏幕)的app,它包含一个文本框和一个按键。在这节课里,你将会向MainActivity添加一些代码,使得用户点击Send按键后开始一个新的activity。
Respond to the Send Button —— 响应发送按键
To respond to the button's on-click event, open the activity_main.xml
layout file and add the android:onClick
attribute to the <Button>
element:
为了响应按键的点击事件,打开 activity_main.xml
布局文件,并向 <Button>
元素添加 android:onClick
属性。
<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button_send" android:onClick="sendMessage" />
The android:onClick
attribute’s value, "sendMessage"
, is the name of a method in your activity that the system calls when the user clicks the button.
android:onClick
属性的值,"sendMessage",是你的activity中的一个方法名字,当用户点击该按键时系统将调用它。
Open the MainActivity
class (located in the project's src/
directory) and add the corresponding method:
打开 MainActivity
类(放在项目的 src/
目录下),然后添加对应的方法:
/** Called when the user clicks the Send button */ public void sendMessage(View view) { // Do something in response to button }
This requires that you import the View
class:
这要求你导入 View
类:
import android.view.View;
Tip: In Eclipse, press Ctrl + Shift + O to import missing classes (Cmd + Shift + O on Mac).
提示:在Eclipse里,按 Ctrl + Shift + O 来导入缺少的类(Mac里是Cmd + Shift + O)。
In order for the system to match this method to the method name given to android:onClick
, the signature must be exactly as shown. Specifically, the method must:
为了让系统将该方法与android:onClick中给出的方法名称相
匹配,标签必须像上面展示的那样精确。特别的,该方法必须:
- Be public 是public的
- Have a void return value 返回值为void
- Have a
View
as the only parameter (this will be theView
that was clicked) 唯一的参数是一个View
对象(也就是点击后的View
)
Next, you’ll fill in this method to read the contents of the text field and deliver that text to another activity.
下面,你将会使用该方法来读取文本框中的内容,然后将文本发送给另一个activity。
Build an Intent —— 创建一个Intent
An Intent
is an object that provides runtime binding between separate components (such as two activities). The Intent
represents an app’s "intent to do something." You can use intents for a wide variety of tasks, but most often they’re used to start another activity.
一个 Intent
是一个在不同的部件(例如两个activities)之间提供动态绑定的对象。 Intent
代表了一个app“想要做什么”。你可以为很多任务使用intents,但是大多数它们被用于开始另一个activity。
Inside the sendMessage()
method, create an Intent
to start an activity called DisplayMessageActivity
:
在 sendMessage()
方法里,创建一个 an Intent
来开始一个叫 DisplayMessageActivity
的activities:
Intent intent = new Intent(this, DisplayMessageActivity.class);
The constructor used here takes two parameters:
这里的构造器接受两个参数:
- A
Context
as its first parameter (this
is used because theActivity
class is a subclass ofContext
) 第一个参数是一个Context
(因为Activity
类是 Context 的一个子类) - The
Class
of the app component to which the system should deliver theIntent
(in this case, the activity that should be started) 系统应该将该Intent
发送给app中的哪个Class
(在本情况下,就是应该被启动的那个activity)
Sending an intent to other apps
The intent created in this lesson is what's considered an explicit intent, because the Intent
specifies the exact app component to which the intent should be given. However, intents can also be implicit, in which case the Intent
does not specify the desired component, but allows any app installed on the device to respond to the intent as long as it satisfies the meta-data specifications for the action that's specified in various Intent
parameters. For more information, see the class about Interacting with Other Apps.
向其他apps发送一个intent
这节课中创建的intent被认为是一个显式的intent,因为该 Intent
指定了它应该被发送给的明确的app部件。
然而,intents同样可以是隐式的,在这种情况下 Intent
没有指定希望的部件,而是允许设备上安装的任何app来响应该intent,只要它满足 Intent
参数中指定的
动作的元数据规格。更多的信息,请见 Interacting with Other Apps 一课。
Note: The reference to DisplayMessageActivity
will raise an error if you’re using an IDE such as Eclipse because the class doesn’t exist yet. Ignore the error for now; you’ll create the class soon.
注意: 如果你正在使用一个IDE,例如Eclipse,DisplayMessageActivity
的引用将会引起一个错误,因为该类目前并不存在。
An intent not only allows you to start another activity, but it can carry a bundle of data to the activity as well. Inside the sendMessage()
method, use findViewById()
to get the EditText
element and add its text value to the intent:
一个Intent不仅仅允许你开启另一个activity,它还可以向activity带来捆绑的数据。在 sendMessage()
方法里,使用 findViewById()
来得到 EditText
元素,并将它的文本值添加给intent:
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);
Note: You now need import statements for android.content.Intent
and android.widget.EditText
. You'll define the EXTRA_MESSAGE
constant in a moment.
注意:你现在需要导入 android.content.Intent
和 android.widget.EditText
。稍后你将会定义
EXTRA_MESSAGE
常量。
An Intent
can carry a collection of various data types as key-value pairs called extras. The putExtra()
method takes the key name in the first parameter and the value in the second parameter.
一个 Intent
可以携带一系列数据类型作为键-值对,这被称为 extras。 putExtra()方法将第一个参数作为键名,第二个参数作为值。
In order for the next activity to query the extra data, you should define the key for your intent's extra using a public constant. So add the EXTRA_MESSAGE
definition to the top of the MainActivity
class:
为了让下一个activity查询额外的数据,你应该使用公有常量为你的intent的extra定义键。因此,在 MainActivity
类的顶部添加 EXTRA_MESSAGE
的定义。
public class MainActivity extends Activity { public final static String EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE"; ... }
It's generally a good practice to define keys for intent extras using your app's package name as a prefix. This ensures they are unique, in case your app interacts with other apps.
使用你的app的包名作为一个前缀来定义键,通常这是一个很好的习惯。这确保它们是唯一的,如果你app要和其他app交互的话。
Start the Second Activity —— 开始第二个Activity
To start an activity, call startActivity()
and pass it your Intent
. The system receives this call and starts an instance of the Activity
specified by the Intent
.
为了开启一个activity,调用 startActivity()
并把它传递给你的 Intent
。系统接受该方法,并开启该 Intent
中指定的
Activity
的一个实例。
With this new code, the complete sendMessage()
method that's invoked by the Send button now looks like this:
有了这个新的代码,完整的 sendMessage()
(将被Send按键调用)方法如下:
/** Called when the user clicks the Send button */ public void sendMessage(View view) { 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); }
Now you need to create the DisplayMessageActivity
class in order for this to work.
现在你需要创建 DisplayMessageActivity
类,来使得这些能够工作。
Create the Second Activity —— 创建第二个Activity
To create a new activity using Eclipse:
使用Eclipse来创建一个新的activity:
- Click New in the toolbar. 点击工具栏上的 New 。
- In the window that appears, open the Android folder and select Android Activity. Click Next. 在出现的对话款里,打开 Android 文件夹,然后选择 Android Activity 。点击 Next。
- Select BlankActivity and click Next. 选择 BlankActivity 并点击 Next 。
- Fill in the activity details: 填写activity细节:
- Project: MyFirstApp
- Activity Name: DisplayMessageActivity
- Layout Name: activity_display_message
- Title: My Message
- Hierarchial Parent: com.example.myfirstapp.MainActivity
- Navigation Type: None
Click Finish. 点击 完成。
If you're using a different IDE or the command line tools, create a new file named DisplayMessageActivity.java
in the project's src/
directory, next to the original MainActivity.java
file.
如果你使用一个不同的IDE或者是命令行工具,在项目的 src/
目录下创建一个新的文件,名为 DisplayMessageActivity.java
,紧跟着原来的 MainActivity.java
文件。
Open the DisplayMessageActivity.java
file. If you used Eclipse to create this activity:
打开 DisplayMessageActivity.java
文件。如果你使用Eclipse来创建该activity:
- The class already includes an implementation of the required
onCreate()
method. 该类已经包含了需要的onCreate()
方法的一个实现。 - There's also an implementation of the
onCreateOptionsMenu()
method, but you won't need it for this app so you can remove it. 这里还有一个onCreateOptionsMenu()
方法的实现,但在这个app里你将不会用到它,因此你可以把它删除了。 - There's also an implementation of
onOptionsItemSelected()
which handles the behavior for the action bar's Up behavior. Keep this one the way it is. 同时还有一个onOptionsItemSelected()
方法的实现,它负责工具栏上 Up 的行为。不用管它。
Because the ActionBar
APIs are available only on HONEYCOMB
(API level 11) and higher, you must add a condition around the getActionBar()
method to check the current platform version. Additionally, you must add the @SuppressLint("NewApi")
tag to the onCreate()
method to avoid lint errors.
因为 ActionBar
APIs 仅在 HONEYCOMB
(API level 11)或更高版本上才可用,你必须在 getActionBar()
方法外面添加额外的代码来检查当前的平台版本。
The DisplayMessageActivity
class should now look like this:
现在,DisplayMessageActivity
类应该看起来是这样的:
public class DisplayMessageActivity extends Activity { @SuppressLint("NewApi") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_display_message); // Make sure we're running on Honeycomb or higher to use ActionBar APIs if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { // Show the Up button in the action bar. getActionBar().setDisplayHomeAsUpEnabled(true); } } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: NavUtils.navigateUpFromSameTask(this); return true; } return super.onOptionsItemSelected(item); } }
If you used an IDE other than Eclipse, update your DisplayMessageActivity
class with the above code.
如果你在使用除Eclipse外的其他IDE,请使用上面的代码更新你的 DisplayMessageActivity
类。
All subclasses of Activity
must implement the onCreate()
method. The system calls this when creating a new instance of the activity. This method is where you must define the activity layout with the setContentView()
method and is where you should perform initial setup for the activity components.
Activity
的所有子类都必须实现 onCreate()
方法。系统在创建一个新的activity实例时会调用它。在这个方法里,你必须使用 setContentView()
方法定义该activity的布局,并且你应该执行activity部件的初始化操作。
Note: If you are using an IDE other than Eclipse, your project does not contain the activity_display_message
layout that's requested by setContentView()
. That's OK because you will update this method later and won't be using that layout.
注意:如果你正在使用除Eclipse之外的其他IDE,你的项目没有包含 setContentView()需要的
activity_display_message
布局。这是没有问题的,因为你随后将更新这个方法,而不再需要这个布局。
Add the title string —— 添加标题字符串
If you used Eclipse, you can skip to the next section, because the template provides the title string for the new activity.
如果你使用过Eclipse,你可以跳到下一章节,因为模板为新的activity提供了标题字符串。
If you're using an IDE other than Eclipse, add the new activity's title to the strings.xml
file:
如果你正在使用除Eclipse之外的其他IDE,向 strings.xml
文件添加新的activity的标题:
<resources> ... <string name="title_activity_display_message">My Message</string> </resources>
Add it to the manifest —— 将它添加到清单
All activities must be declared in your manifest file, AndroidManifest.xml
, using an <activity>
element.
所有的activities必须使用一个 <activity>
元素在你的清单文件,AndroidManifest.xml
, 里声明。
When you use the Eclipse tools to create the activity, it creates a default entry. If you're using a different IDE, you need to add the manifest entry yourself. It should look like this:
当你使用Eclipse工具来创建activity时,它创建了一个默认的入口。如果你使用一个不同的IDE,你需要手动添加清单入口。它看起来应该是这样的:
<application ... > ... <activity android:name="com.example.myfirstapp.DisplayMessageActivity" android:label="@string/title_activity_display_message" android:parentActivityName="com.example.myfirstapp.MainActivity" > <meta-data android:name="android.support.PARENT_ACTIVITY" android:value="com.example.myfirstapp.MainActivity" /> </activity> </application>
The android:parentActivityName
attribute declares the name of this activity's parent activity within the app's logical hierarchy. The system uses this value to implement default navigation behaviors, such as Up navigation on Android 4.1 (API level 16) and higher. You can provide the same navigation behaviors for older versions of Android by using the Support Library and adding the <meta-data>
element as shown here.
android:parentActivityName
属性声明了该activity在app的逻辑层次中父activity的名字。系统使用这个值来实现默认的导航动作,例如Android 4.1(API level 16)或更高版本上的 Up navigation 。你可以使用Support Library 、并添加 <meta-data>
为更老的Android版本提供相同的导航动作,正如这里展示的一样。
Note: Your Android SDK should already include the latest Android Support Library. It's included with the ADT Bundle but if you're using a different IDE, you should have installed it during the Adding Platforms and Packages step. When using the templates in Eclipse, the Support Library is automatically added to your app project (you can see the library's JAR file listed under Android Dependencies). If you're not using Eclipse, you need to manually add the library to your project—follow the guide for setting up the Support Library then return here.
注意:你的Android SDK应该已经包含了最新的Android Support Library。它被包含在ADT Bundle中,但是如果你正在使用一个不同的IDE,你应该已经在 Adding Platforms and Packages 一步里安装了它。当在Eclipse里使用模板时,Support Library 被自动添加到你的app项目里(你可以看到 Android Dependencies 下列出的 library's JAR 文件)。
If you're developing with Eclipse, you can run the app now, but not much happens. Clicking the Send button starts the second activity but it uses a default "Hello world" layout provided by the template. You'll soon update the activity to instead display a custom text view, so if you're using a different IDE, don't worry that the app won't yet compile.
如果你正在使用Eclipse进行开发,你现在可以运行app了,但是不会发生很多事情。点击Send按键开始了第二个activity,但是它使用模板提供的默认的"Hello world"布局。你将马上更新这个activity来显示一个用户文本视图,因此如果你正在使用一个不同的IDE,不要担心这个app不会编译通过。
Receive the Intent —— 接收该Intent
Every Activity
is invoked by an Intent
, regardless of how the user navigated there. You can get the Intent
that started your activity by calling getIntent()
and retrieve the data contained within it.
每一个 Activity
都被一个 Intent
调用,不管用户是如何导航到此处。你可以通过调用
getIntent()
来得到开启你的activity的 Intent
,然后检索到它包含的数据。
In the DisplayMessageActivity
class’s onCreate()
method, get the intent and extract the message delivered by MainActivity
:
在 DisplayMessageActivity
的 onCreate()
方法里,得到 MainActivity
发送的intent和精确的信息:
Intent intent = getIntent(); String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
Display the Message —— 显示信息
To show the message on the screen, create a TextView
widget and set the text using setText()
. Then add the TextView
as the root view of the activity’s layout by passing it to setContentView()
.
为了将信息显示在屏幕上,创建一个 TextView
部件,使用setText()来设置文本。然后通过把它传递给setContentView()来将该 TextView
设为activity布局的的根视图,
The complete onCreate()
method for DisplayMessageActivity
now looks like this:
DisplayMessageActivity
的完整的 onCreate()
方法如下:
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Get the message from the intent Intent intent = getIntent(); String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE); // Create the text view TextView textView = new TextView(this); textView.setTextSize(40); textView.setText(message); // Set the text view as the activity layout setContentView(textView); }
You can now run the app. When it opens, type a message in the text field, click Send, and the message appears on the second activity.
你现在可以运行app了。当它开启时,在文本框输入一个信息,点击Send,然后该信息将出现在第二个activity上。
That's it, you've built your first Android app!
现在,你已经建立了你的第一个Android app!
To learn more about building Android apps, continue to follow the basic training classes. The next class is Managing the Activity Lifecycle.
学习更多的关于如何创建Android apps,请继续学习基础训练课程。下一节课是 Managing the Activity Lifecycle 。