Activity讲解
Activity
Activity 是 Android 应用的重要组成单元之一(另外三个是 Service、BroadcastReceiver 和 ContentProvider),而 Activity 又是 android 应用最常见的组件之一。前面看到的示例通常都只包含一个 Activity,但在实际应用中这个是不太可能的,往往包括多个 Activity,不同的 Activity 向用户呈现不同的操作界面。android 应用的多个 Activity 组成 Activity 栈,当前活动的 Activity 位于栈顶。
建立、配置和使用 Activity
-
建立自己的 Activity 也需要继承 Activity 基类。当然,在不同应用场景下,有时也要求继承 Activity 的子类。例如,如果应用程序界面只包括列表,则可以让应用程序继承 ListActivity;如果应用程序界面需要实现标签页效果,则可以让应用程序继承 TabActivity。
-
Activity 类间接或直接地继承了 Context、ContextWrapper、ContextThemeWrapper 等基类,因此 Activity 可以直接调用它们的方法。
-
创建一个 Activity 也需要实现一个或多个方法,其中最常见的就是实现 onCreate(Bundle status)方法,该方法将会在 Activity 创建时被回调,该方法调用 Activity 的 setContentView(View view)方法来显示要展现的 View。为了管理应用程序界面的各组件,调用 Activity 的 findViewById(int id)方法来获取程序界面中的组件,接下来修改各组件的属性和方法即可。
-
实例讲解
- 下面以安卓疯狂讲义中的例子来进行讲述
- 实例:用 LauncherActivity 开发启动 Activity 的列表
LauncherActivity 继承了 ListActivity,因此它本质上也是一个开发列表界面的 Activity,但它开发出来的列表界面与普通列表界面有所不同。它开发出来的列表界面中每个列表项都对应一个 Intent,因此当用户单击不同的列表项时,应用程序会自动启动对应的 Activity。
使用 LauncherActivity 的方法并不难,由于依然是一个 ListActivity,因此同样需要为它设置 Adapter—-即可使用简单的 ArrayAdapter,也可使用 SimpleAdapter,当然还可以扩展 BaseAdapter 来实现自己的 Adapter。与使用普通 ListActivity 不同的是,继承 LauncherActivity 时通常应该重写 Intent intentForPosition(int position)方法,该方法根据不同列表项返回不同的 Intent(用于启动不同的 Activity)
public class MainActivity extends LauncherActivity {
//定义两个Activity的名称
String[] names = {"设置程序参数", "查看星际兵种"};
//定义两个Activity对应的实现类
Class<?>[] clazzs = {PreferenceActivityTest.class
, ExpandableListActivityTest.class};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, names);
// 设置该窗口显示的列表所需的Adapter
setListAdapter(adapter);
}
//根据列表项返回指定Activity对应的Intent
@Override
public Intent intentForPosition(int position) {
return new Intent(MainActivity.this, clazzs[position]);
}
}
上面程序还用到了如下两个 Activity
- ExpandableListActivityTest:它是 ExpandableListActivity 的子类,用于显示一个可展开的列表窗口。
- PreferenceActivityTest:它是 PreferenceActivity 的子类,用于显示一个显示设置选项参数并进行保存的窗口。
- 实例:使用 ExpandableListActivity 实现可展开的 Activity
ExpandableListActivity 的用法与前面介绍的 ExpandableListView 的用法基本相似,只要为该 Activity 传入一个 ExpandableListAdapter 对象即可,接下来 ExpandableListActivity 将会生成一个显示可展开列表的窗口。
public class ExpandableListActivityTest extends ExpandableListActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ExpandableListAdapter adapter = new BaseExpandableListAdapter() {
int[] logos = new int[]
{
R.drawable.p,
R.drawable.z,
R.drawable.t
};
private String[] armTypes = new String[]
{"神族兵种", "虫族兵种", "人族兵种"};
private String[][] arms = new String[][]
{
{"狂战士", "龙骑士", "黑暗圣堂", "电兵"},
{"小狗", "刺蛇", "飞龙", "自爆飞机"},
{"机枪兵", "护士MM", "幽灵"}
};
//获取指定组位置、指定子列表项处的子列表项数据
@Override
public Object getChild(int groupPosition, int childPosition) {
return arms[groupPosition][childPosition];
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public int getChildrenCount(int groupPosition) {
return arms[groupPosition].length;
}
private TextView getTextView() {
AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, 64);
TextView textView = new TextView(ExpandableListActivityTest.
this);
textView.setLayoutParams(lp);
textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
textView.setPadding(36, 0, 0, 0);
textView.setTextSize(20);
return textView;
}
//该方法决定每个子选项的外观
@Override
public View getChildView(int groupPosition, int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
TextView textView = getTextView();
textView.setText(getChild(groupPosition, childPosition).
toString());
return textView;
}
//获取指定组位置处的组数据
@Override
public Object getGroup(int groupPosition) {
return armTypes[groupPosition];
}
@Override
public int getGroupCount() {
return armTypes.length;
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
//该方法决定每个组选项的外观
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
LinearLayout ll = new LinearLayout(
ExpandableListActivityTest.this);
ll.setOrientation(LinearLayout.HORIZONTAL);
ImageView logo = new ImageView(
ExpandableListActivityTest.this);
logo.setImageResource(logos[groupPosition]);
ll.addView(logo);
TextView textView = getTextView();
textView.setText(getGroup(groupPosition).toString());
ll.addView(textView);
return ll;
}
@Override
public boolean isChildSelectable(int groupPosition,
int childPosition) {
return true;
}
@Override
public boolean hasStableIds() {
return true;
}
};
// 设置该窗口显示列表
setListAdapter(adapter);
}
}
配置 Activity
- android 应用要求所有应用程序组件(Activity、Service、ContentProvider、BroadcastReceiver)都必须显式进行配置。
- 只要为< application…/ >元素添加< activity… >子元素即可配置 Activity。例如如下的配置片段:
<activity android:name=".SampleActivity"
android:icon="@drawable/small_pic.png"
android:label="@string/freneticLabel"
android:exported="true"
android:launchMode="singleInstance"
- 从上面的配置片段可以看出,配置 Activity 时通常指定如下几个属性。
- name:指定该 Activity 的实现类的类名。
- icon:指定该 Activity 对应的图标。
- label:指定该 Activity 的标签。
- exported:指定该 Activity 是否允许被其他应用调用。如果将该属性设为 true,那么该 Activity 将可以被其他应用调用。
- launchMode:指定该 Activity 的加载模式,该属性支持 standard、singleTop、singleTask 和 singleInstance 这 4 种加载模式。
- 除此之外,配置 Activity 时通常还需要指定一个或多个< intent-filter…/ >元素,该元素用于指定 Activity 可响应的 Intent。
- 为了在 AndroidManifest.xml 文件中配置、管理上面的三个 Activity,可以在清单文件的< application…/ >元素中增加如下三个< activity…/ >子元素。
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.yonga.app" >
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity android:name=".MainActivity"
android:label="@string/app_name">
<!-- 指定该Activity是程序的入口 -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- 定义两个Activity -->
<activity android:name=".ExpandableListActivityTest"
android:label="查看星际兵种">
</activity>
<activity android:name=".PreferenceActivityTest"
android:label="设置程序参数">
</activity>
</application>
</manifest>
- 上面的配置片段配置了三个 Activity,其中第一个 Activity 还配置了一个< intent-filter…/>元素,该元素指定该 Activity 作为应用程序的入口。
启动、关闭 Activity
正如前面所介绍的,一个 android 应用通常都会包含多个 Activity,但只有一个 Activity 会作为程序的入口—-当该 android 应用运行时将会自动启动并执行该 Activity。至于应用中得其他 Activity,通常都由入口 Activity 启动,或由入口 Activity 启动的 Activity 启动。
- Activity 启动其他 Activity 有如下两个方法。
- startActivity(Intent intent):启动其他 Activity。
- startActivityForResult(Intent intent,int requestCode):以指定的请求码(requestCode)启动 Activity,而且程序将会获取新启动的 Activity 返回的结果(通过重写 onActivityResult(…)方法来获取)。
启动 Activity 时可指定一个 requestCode 参数,该参数代表了启动 Activity 的请求码,这个请求码的值由开发者根据业务自行设置,用于标识请求来源。
上面两个方法都用到了 Intent 参数,Intent 是 android 应用里各组件之间通信的重要方式。一个 Activity 通过 Intent 来表达自己“意图”—-想要启动哪个组件,被启动的组件即可是 Activity 组件,也可是 Service 组件。
- android 为关闭 Activity 准备了如下两个方法。
- finish():结束当前 Activity。
- finishActivity(int requestCode): 结束以 startActivityForResult(Intent intent,int requestCode)方法启动的 Activity。
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 获取应用程序中的bn按钮
Button bn = (Button) findViewById(R.id.bn);
// 为bn按钮绑定事件监听器
bn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View source) {
// 创建需要启动的Activity对应的Intent
Intent intent = new Intent(MainActivity.this,
SecondActivity.class);
// 启动intent对应的Activity
startActivity(intent);
}
});
}
}
public class SecondActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second);
// 获取应用程序中的previous按钮
Button previous = (Button) findViewById(R.id.previous);
// 获取应用程序中的close按钮
Button close = (Button) findViewById(R.id.close);
// 为previous按钮绑定事件监听器
previous.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View source) {
// 获取启动当前Activity的上一个Intent
Intent intent = new Intent(SecondActivity.this,
MainActivity.class);
// 启动intent对应的Activity
startActivity(intent);
}
});
// 为close按钮绑定事件监听器
close.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View source) {
// 获取启动当前Activity的上一个Intent
Intent intent = new Intent(SecondActivity.this,
MainActivity.class);
// 启动intent对应的Activity
startActivity(intent);
// 结束当前Activity
finish();
}
});
}
}