调用另一个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);
}
运行结果如下: