Fork me on GitHub

【Android Developers Training】 4. 启动另一个Activity

注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好。

原文链接:http://developer.android.com/training/basics/firstapp/starting-activity.html


 一. 启动另一个Activity

在完成了之前的课程后,你已经拥有了一个显示一个Activity(即只有一个屏幕画面)的应用,在这个Activity中有一个文本框和一个按钮。在这节课上,你将在MainActivity中添加一些新的代码,这些代码将实现:当用户点击按钮后,可以启动一个新的Activity。

 

一). 发送按钮的响应

为了响应按钮点击事件,打开布局文件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" />

android:onClick的值为“sendMessage”,它在你的Activity中的一个方法的名字,当用户点击这个按钮时,系统会调用这个方法。

打开MainActivity类(在项目工程的/src目录下),然后添加响应的方法:

/** Called when the user clicks the Send button */
public void sendMessage(View view) {
    // Do something in response to button
}

这需要你导入View类:

import android.view.View;

Tip:

在Eclipse中,按下“Ctrl + Shift + O”可以自动导入丢失的类(在Mac上的组合键是:“Cmd + Shift + O”)。

为了让系统能够将这个方法和它在android:onClick属性字段中的方法名这两者相互关联起来,这个方法的特征必须严格地像上述所表示的那样,具体来说,方法的特征有如下几点:

  • 必须是Public
  • 返回值为void
  • 只有一个形参View(这个View就是被点击的View

接下来,你将会实现这个方法,我们用它来读取文本框中的内容并且将文字发送给另一个Activity

 

二). 构建一个Intent

Intent是一种对象,它是在运行时将两个独立的组件(比如两个Activity)联系起来的纽带。Intent代表了一个应用的某种“意图”,你可以使用Intent去完成很多事情,但通常他们被用来启动另一个Activity。

sendMessage()这一方法中,创建一个新的Intent来启动另一个称之为DisplayMessageActivity的Activity:

Intent intent = new Intent(this, DisplayMessageActivity.class);

这里的构造函数包含了两个参数:

  • 一个Context作为第一个参数(这里用this的原因是ActivityContext的一个子类)。
  • 应用组件中的某个Class,它是系统送达Intent的目标(在此例中,对应的是将要被启动的Activity

Note:

若你正在使用的是一个集成开发环境(IDE),如:Eclipse,那么对DisplayMessageActivity的引用将会引起一个错误,原因是目前这个类还并不存在。我们现在先暂且忽略这个错误,你马上就将创建这个类。

一个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:

你现在需要导入一些声明:android.content.Intentandroid.widget.EditText。稍后你将会定义EXTRA_MESSAGE常量。

将Intent发送给其他应用:

这节课中所创建的Intent,我们将它称之为“显式的Intent”,因为这个Intent指明了自己将会发送给哪一个特定的应用组件。然而,Intent也可以是隐式的”,在这种情况下,Intent不指明自己期望被发送到哪个组件,但允许任何安装在设备上的应用响应这个Intent,只要它的行为的元数据规格与之相匹配,可以通过阅读Interacting with Other Apps获得更多信息。

一个Intent携带以键值对形式存放的各种数据类型,在Intent中这些键值对被称之为extrasputExtra()方法中第一个参数对应于键,第二个参数对应于值。

为了让下一个Activity可以查询extras的数据,你应该使用一个公共常量来定义Intentextras中的键。所以在MainActivity类的顶端,添加EXTRA_MESSAGE的定义:

public class MainActivity extends Activity {
    public final static String EXTRA_MESSAGE = "com.example.myfirstapp.MESSAGE";
    ...
}

Intent extras的键定义时,将你应用的包名作为前缀是一个好的习惯,这样可以保证他们是唯一的,这有助于你的应用和其他应用进行通信。

 

三). 启动第二个Activity

为了启动一个Activity,调用startActivity()方法,并且将你的Intent对象传递给它。之后系统接受到函数的调用,并且启动一个被Intent所指定的Activity实例。

加上了新的代码后,被Send按钮所调用的sendMessage()方法的完整代码如下所示:

/** 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);
}

现在你需要创建DisplayMessageActivity类使得它能够正确运行。

 

四). 创建第二个Activity

使用Eclipse创建第二个类:

  1. 在工具栏中点击“New
  2. 在出现的窗口中,打开Android”文件夹,选择Android Activity”,点击Next
  3. 选择BlankActivity点击Next
  4. 填写Activity的细节信息:
    • Project: MyFirstApp
    • Activity Name: DisplayMessageActivity
    • Layout Name: activity_display_message
    • Title: My Message
    • Hierarchial Parent: com.example.myfirstapp.MainActivity
    • Navigation Type: None

点击Finish

图1. Eclipse中创建新Activity的向导

如果你使用的是不同的IDE,或者是命令行,在项目工程中的src/”创建一个新的名为“DisplayMessageActivity.java”的文件,这个文件紧随最初的MainActivity.java文件。

打开DisplayMessageActivity.java”,如果你使用的是Eclipse创建的它:

  • 这个类已经包含了一个必须的onCreate()方法的实现
  • 同时还有onCreateOptionsMenu()方法的实现,但在这个应用中我们不需要它,所以你可以将它删除
  • 同时还有一个onOptionsItemSelected()方法的实现,这个方法处理标题栏(Action Bar)的处理上一页(Up)事件时的行为。我们保持它原有的样子。

因为ActionBar的APIs仅在HONEYCOMB(API Level 11)及更高的版本中才有,所以你必须在getActionBar()方法处添加一个条件判断,用来检查当前的平台版本。另外,你必须在onCreate()方法处添加一个标签:“@SuppressLint("NewApi")”,以此来避免lint错误。

现在,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);
    }
}

如果你使用的IDE不是Eclipse,使用上述代码更新你的DisplayMessageActivity类。

所有Activity的子类必须实现onCreate()方法。当系统创建Activity的实例时,会调用这个方法。在这个方法中,你通过使用setContentView()方法定义activity的的布局,同时对activity的组件进行初始化设置。

Note:

如果你使用的IDE不是Eclipse,你的项目工程将不会包括setContentView()所需要的布局文件activity_display_message,这没有关系,因为你马上将会对这个方法进行更新并且不再需要这个布局。

 

添加标题字符

如果你使用的是Eclipse,你可以跳过这一节,因为自动创建的模板为新的activity提供了标题字符。

如果你使用的IDE不是Eclipse,在“strings.xml”添加新activity的标题字符:

<resources>
    ...
    <string name="title_activity_display_message">My Message</string>
</resources>

 

添加至清单

在你的清单文件AndroidManifest.xml中,所有activity必须通过使用一个<activity>标签被声明。

当你使用Eclipse工具创建这个activity时,它会创建一个默认的条目,如果你使用的不是Eclipse,你需要自己添加这个清单条目,修改后的结果如下:

<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>

其中android:parentActivityName属性字段声明了在应用的逻辑结构中该activity的父activity的名字。系统使用这一属性值来实现默认的导航行为,比如在Android 4.1版本(API Level 16)或更高版本中的Up navigation行为。你可以为较旧版本的Android系统提供相同的导航行为,这可以通过使用Support Library并且添加<meta-data>标签来实现,如同此例所示。

 Note:

你的Android SDK应该已经拥有了最新的Android Support Library,它包含在ADT中。但如果你用的是其他的IDE,你应该在Adding Platforms and Packages这一步中已经将它安装好。当在Eclipse中使用模板时,Support Library就被自动地添加到你的项目中了(你可以在Android Dependencies下看到这个库的JAR文件)。如果你使用的不是Eclipse,你需要手动将它添加至你的项目,按照如下导引一步步执行即可:setting up the Support Library

如果你使用的是Eclipse,你现在已经可以运行这个应用了,但是没有什么事情发生。点击发送按钮会启动第二个Activity,但是它使用的是默认的“Hello World”模板作为布局。你很快就将更新这个activity,使它显示一个自定义的文本框,若你使用的是其他IDE,不用担心目前自己应用还无法编译的问题。

 

 

五). 接受Intent

无论用户是如何被指引到那儿的,每个Activity都是被一个Intent启动的。你可以通过调用getIntent()方法来获得启动你的activityIntent,进而收回它所携带的数据。

DisplayMessageActivity类中的的onCreate()方法里,提取由MainActivity发送的数据:

Intent intent = getIntent();
String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);

 

六). 显示消息

为了在屏幕上显示消息,创建一个TextView控件,然后使用setText()方法设置它要显示的文本。之后将TextView传递给setContentView(),这样TextView就成为了这个activity的根View。

DisplayMessageActivityonCreate()方法的完整代码如下:

@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);
}

现在你可以运行这个应用。当它打开后,在文本框里输入一些文字,点击发送,然后这些文字将会在第二个activity中显示出来。

图2. 在Android4.0设备上的运行结果

 

就是这样,你已经构建好了你的第一个应用了!

posted @ 2013-11-24 15:57  __Neo  阅读(482)  评论(0编辑  收藏  举报