调用另一个activity

读完上一篇文章 之后在app中显示出了文本输入框和按钮,这篇文章我们会在MainActivity中添加代码,当点击send按钮之后,调用另外一个activity。

响应send按钮的点击事件

我们直接通过 button的 android:onClick 属性来关联点击事件:

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/button_send"
    android:onClick="sendMessage" />

译者注:开发安卓半年第一次见识可以这样。。。一直都是在java代码里面设置点击事件。

android:onClick的值"sendMessage"是当点击按钮的时候调用的activity中的方法名。

打开src目录中的`MainActivity`文件,在类中添加如下方法:

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

由于方法的参数中有View类,因此你需要引入相应的包

import android.view.View;

为了让系统在点击按钮的时候自动调用到sendMessage方法,你的方法必须遵守如下约定:

1.必须是public方法;

2.必须是void返回类型;

3.必须带有一个View形参(表示被点击的究竟是哪个View);

下面,我们完善这个方法,让button被点击之后读取文本框的字符串,并将该字符串传递给另外一个activity。

新建一个意图Intent

Intent对象是绑定两个组件之间的运行时绑定(比如两个activity之间),intent代表一个app要做什么事的意图。Intent的用处很多,但是最常见的是调用另外一个activity。

我在需要sendMessage()方法中创建一个intent对象来调用叫DisplayMessage 的activity。所以intent对象的创建应该这样写:

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

Intent对象的构造方法有两个参数:

Context参数(第一个参数),因为activity是Context类的子类,所以我们可以传入this。

系统所要将Intent传递给他的app组件(本例中就是一个activity),因为我们还没有定义DisplayMessageActivity所以如果你是在eclipse中建立的工程的话,会出现错误提示。

一个意图不仅能让你调用activity,而且能携带数据,通过下面的代码我们将文本框中的字符串打包进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);

Intent能以键值对的形式传递各种各样的数据,这些数据成为额外数据extras。putExtra()方法第一个参数是键,第二个参数是这个键对应的值。为了让下一个activity能接收到Intent所包含的额外数据,你你需要将键定义成一个public常量。一般这些常量都是定义在一个java文件的最上面。

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

我们建议你的intent数据键值对的键以你的包名为前缀,这能确保这个常量是唯一的,避免和其他app相冲突。

启动第二个activity

要调用第二个activity,需要调用startActivity()并传入刚刚定义好的Intent对象,完善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中新建一个activity的步骤如下:

1.点击工具栏中的新建按钮。

2.在出现的界面中选择android目录下的Android Activity一项,然后点击下一步。

3.选中BlankActivity然后点击下一步,然后就出现了上图那个界面。

4.在出现的界面里填写activity的详细信息。

属于哪一个工程:MyFirstApp

Activity名:DisplayMessageActivity

Activity的布局文件:activity_display_message

Activity的标题:My Message

Activity的父类:com.example.myfirstapp.MainActivity

导航类型:无。

填写完后点击完成。

如果你是用的其他ide来创建的工程,或者用的是命令行的方式,在src目录下新建一个DisplayMessageActivity.java文件,也行,不过这时你activity的引用布局文件就需要自己写在相应的地方(译者注:本人一般都是采用第二种方式,也多不了几个步骤,感觉上也要自在些。)

打开DisplayMessageActivity.java文件,如果你是在eclispe上严格按照上面的步骤建立的activity的话那么在DisplayMessageActivity.java文件中就已经有了onCreate,onCreateOptionsMenu,onOptionsItemSelected这些必备的方法了。

ActionBar api是最近几个版本(API level 11)才有的新特性,你需要通过getActionBar()方法来检查当前版本。

现在 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 higherto use ActionBar APIs
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
            // Show the Up button in the actionbar.
            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);
    }
}

如果你不是用的eclispe或者是自己手动添加的DisplayMessageActivity.java的话,直接将上面的代码复制粘贴到你的DisplayMessageActivity中去。

一个activity必须继承onCreate方法,每当一个activity在新建一个新实例的时候系统都会自动调用这个方法。你应该在onCreate方法中初始化视图组件、使用setContentView来定义你的activity布局文件等一些列初始化操作。

注意setContentView(R.layout.activity_display_message);这行代码引用了布局资源文件activity_display_message.xml如果你的代码是手动添加的,你一会儿自己新建一个。这个例子中是新建activity的时候eclispe向导自动生成的。

添加activity的title所需要的资源文件

如果你是用上面介绍的eclipse添加activity的向导新建的activity,那么你可以直接跳过这一步,因为eclispe已经生成了。

在string.xml文件中新增一个字符串:

<resources>
    ...
    <string name="title_activity_display_message">MyMessage</string>
</resources>

在manifest中添加这个activity

所有的activity都必须在AndroidManifest.xml文件中用标签事先声明。

代码如下:

<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)版本actionbar的向上(返回上一级)操作。

注:在编译android代码之前必须确保安装了sdk,Eclispe中,ADT Bundle已经包含了SDK,需要的库文件在工程文件的_Android Dependencies列表里可以找到,_因此不用考虑这个问题;但如果是其他开发环境,你可以参考这篇文章:setting up the Support Library。

接收Intent

不管以什么形式,也不管activity是如何启动的,每个activity都是由Intent来激发的。通过activity的getIntent()方法可以得到激发该activity的Intent,以及Intent中包含的数据信息。

在DisplayMessageActivity文件中,我们将如下代码放在onCreate()里面来获得MainActivity 传入的intent.

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

显示Intent消息

我们新建一个TextView控件来,通过setText()方法来设置要显示的内容。这个TextView控件是充满整个屏幕的,setContentView()方法可以将一个View添加进activity,并且让该View在最顶层。

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

运行结果如下: