前面的文章已经讲到了如何在一个Activity中与用户进行交互。这篇文章将解释如何创建多个Activity的用户界面,以及了解Activity的生命周期。这次是一个完整的示例,可以在这里下载源代码。
这个多Activity的示例程序的功能大概是这样的:
- 在主页面上有三个元素:一个文本输入框,两个按钮。用户可以在文本框中输入一些字符
- 点击第一个按钮,将弹出一个对话框形式的Activity,显示”Hello, …”
- 如果点击的是第二个按钮,将显示另一个全屏的Activity,显示”Hello, …”
OK,按照前面的规矩,分成几步:
第1步,先完成UI的设计,创建布局。
从程序来看,似乎有三个Activity,但是第二个和第三个几乎是相同的,于是,只创建两个布局:
res/layout/main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <EditText android:id="@+id/edittext_input" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/button_sayhello_dialog" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello_dialog" /> <Button android:id="@+id/button_sayhello_activity" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello_activity" /> </LinearLayout>
res/layout/dialog.xml
<?xml version="1.0" encoding="utf-8"?> <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/textview_hello" android:text="@string/hello" />
第2步,然后呢,需要把上面提到的字符变量声明一下:
res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello, </string> <string name="hello_dialog">Say Hello(Dialog)</string> <string name="hello_activity">Say Hello(Activity)</string> <string name="app_name">Activity Lifecycle</string> </resources>
通过前面的文章,上面的东西应该都比较好懂。
第3步,创建Activity,这里和第一步一样,虽然有三个Activity,但是看起来用两个其实就够了。然而事实并非如此,具体原因后续,我们需要定义三个Activity:分别将他们定义为:ActivityLifecycle(用来显示主画面)、AlertDialog(用来显示对话框)和AlertActivity(用来显示那个全屏的Activity)。
主Activity:
package com.roiding.sample;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class ActivityLifecycle extends Activity {
private static final String TAG = "ActivityLifecycle";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "onCreate ...");
setContentView(R.layout.main);
final EditText editText = (EditText) findViewById(R.id.edittext_input);
// try to display a dialog
Button btn_dialog = (Button) findViewById(R.id.button_sayhello_dialog);
btn_dialog.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent();
intent.putExtra("name", editText.getText().toString());
intent.setClass(ActivityLifecycle.this, AlertDialog.class);
startActivity(intent);
}
});
// try to display a activity
Button btn_activity = (Button) findViewById(R.id.button_sayhello_activity);
btn_activity.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent();
intent.putExtra("name", editText.getText().toString());
intent.setAction("com.roiding.sample.action.MAIN");
startActivity(intent);
}
});
}
@Override
public void onStart() {
super.onStart();
Log.i(TAG, "onStart ...");
}
@Override
public void onResume() {
super.onResume();
Log.i(TAG, "onResume ...");
}
@Override
public void onPause() {
super.onPause();
Log.i(TAG, "onPause ...");
}
@Override
public void onStop() {
super.onStop();
Log.i(TAG, "onStop ...");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy ...");
}
@Override
public void onRestart() {
super.onDestroy();
Log.i(TAG, "onRestart ...");
}
}
在这里面:
以下语句,前文都提到过:
- final EditText editText = (EditText) findViewById(R.id.edittext_input)
- btn_dialog.setOnClickListener(new OnClickListener())
主要说一下这些:
- Log.i(TAG, “onStart …”);
这是Android中日志的处理方式,用法于Log4j类似,但是要比Log4j简单的多,因为用的几乎都是static的方法。分别是Log.v 、 Log.d 、 log.i、 log.w、 log.e。使用Log打印的日志通过LogCat可以看到。方法中的第一个属性一般用来标识一下日志是谁打印出来的,便于查找。 - Intent intent = new Intent();
对UI来说,这里面的Intent是一个非常重要的概念(几个重要的概念了?)。并且要理解它会比理解View、Activity什么的要困难一些,这部 分会在单独的一篇文章中讨论。在这里,只需要知道:通过它,可以找到下一个要显示的Activity,并为这个Activity携带了一些数据。也就是说 它有两个重要的使命:定位下一个Activity;并捎带一些数据。所以在Android的文档中,称Intent为Activity之间的双面胶。更详 细的解释留待后面的某篇文章中吧。 - startActivity(intent);
通过startActivity(intent)可以启动并显示另外一个Activity。
第2个Activity
package com.roiding.sample;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
public class AlertDialog extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog);
Intent intent = getIntent();
String name = (String) intent.getExtras().get("name");
TextView textview = (TextView) findViewById(R.id.textview_hello);
if (name != null) {
String hello = getResources().getString(R.string.hello);
textview.setText(hello + name);
}
}
}
在这个Activity里面,只有一个语句需要解释一下:
- String name = (String) intent.getExtras().get(”name”);
用来获得前面Activity捎带过来的数据
第3个Activity和第2个几乎完全一样:
package com.roiding.sample;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
public class AlertActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog);
Intent intent = getIntent();
String name = (String) intent.getExtras().get("name");
TextView textview = (TextView) findViewById(R.id.textview_hello);
if (name != null) {
String hello = getResources().getString(R.string.hello);
textview.setText(hello + name);
}
}
}
到这一步,所有的事情似乎都已经完成了,可以运行了,如果在这时你等不及而去运行程序,将会得到一些ActivityNotFoundException 之类的异常。这里还需要一步,如果以前写的程序都是单Activity的,那么Eclipse的Android插件会自动完成这一步,如果是多 Activity的,或者需要对Activity作更仔细的控制,那么就要这一步了。
第4步,编辑AndroidManifest.xml
这个文件像一个户口簿一样记录每一个Activity的信息,Android系统会通过这个文件得到:执行这个程序的时候,启动的是那个Activity 等信息。不仅如此,这个还包括Intent、Provider等其他一些信息。如果你用过一些Web MVC框架的话,这个文件的功能就像是那个MVC的配置文件。
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.roiding.sample" android:versionCode="1" android:versionName="1.0.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".ActivityLifecycle" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".AlertDialog" android:theme="@android:style/Theme.Dialog" android:label="@string/app_name"> </activity> <activity android:name=".AlertActivity" android:label="@string/app_name"> <intent-filter> <action android:name="com.roiding.sample.action.MAIN" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> </application> </manifest>
注意这里面的第二个和第三个Activity声明方式不一样,这个留待讲述Intent的时候再讲。
好了,我们可以运行这个程序了。
看起来篇幅似乎过长了,那么关于Activity的生命周期放在下一篇文章中。
January 8th, 2010 at 11:06
博主Android的UI系列文章写得很好啊。
建议能把这一系列的文章做一个目录,这样就更系统了。
我们看着也方便多了。要不然每次找文章都要站内搜索。
呵呵~~
May 19th, 2010 at 7:13
Hello! addgdce interesting addgdce site!
May 19th, 2010 at 7:13
Very nice site! cheap viagra
May 19th, 2010 at 7:13
Very nice site! [url=http://aixopey.com/qqatat/2.html]cheap cialis[/url]
May 19th, 2010 at 7:13
Very nice site! cheap cialis http://aixopey.com/qqatat/4.html
May 19th, 2010 at 7:13
Very nice site!
June 11th, 2010 at 11:43
I feel I allready have been acknowledged about this subject
at bar 2 days ago by a colleague, but at that moment
it didn’t caugh my attention.
June 16th, 2010 at 4:34
with this in mind, it is so important that we live, our lives… alive
June 17th, 2010 at 2:17
How much more enjoyable to read about your journey now.
June 27th, 2010 at 1:54
To be a noble lenient being is to procure a amiable of openness to the mankind, an cleverness to trust uncertain things beyond your own manage, that can govern you to be shattered in very extreme circumstances as which you were not to blame. That says something uncommonly outstanding relating to the get of the principled passion: that it is based on a trust in the up in the air and on a willingness to be exposed; it’s based on being more like a shop than like a sparkler, something somewhat dainty, but whose very precise beauty is inseparable from that fragility.
June 28th, 2010 at 8:46
http://www.roiding.com is very the most informative. I liked your blog a lot. Thank you.
June 29th, 2010 at 5:19
I was completely astonished after reading the article.
July 11th, 2010 at 1:08
http://www.roiding.com is great! Getting a loan is much easier nowadays Everybody is becoming more dependent on loans so as to make ends meet However if you want an instant and fastest way of borrowing money just avail of faless payday loans
July 16th, 2010 at 2:19
I’m in agreement
July 17th, 2010 at 5:18
i really enjoyed your post.
July 18th, 2010 at 6:21
In everyone’s existence, at some occasion, our inner fire goes out. It is then bust into enthusiasm by an encounter with another human being. We should all be under obligation for the duration of those people who rekindle the inner transport
July 23rd, 2010 at 11:55
Classic!!