在进一步学习 Intent 与 Activity 之前,我们先来完善我们的应用程式。 在前几章中,我们把 「openOptionsDialog」 这个用来弹出对话框的函式,放进「calcBMI」这个按钮元件的「OnClickListener」方法中。现在,我们要把「openOptionsDialog」 移出「OnClickListener」方法,改成按下「Menu」键后,跳出一个选单列(Menu Bar)。当我们点击选单列中的选项后,才弹出 「openOptionsDialog」 的对话框。
完整的程式码如下:
1 protected static final int MENU_ABOUT = Menu.FIRST;
2 protected static final int MENU_Quit = Menu.FIRST+1;
3
4 @Override
5 public boolean onCreateOptionsMenu(Menu menu) {
6 super.onCreateOptionsMenu(menu);
7 menu.add(0, MENU_ABOUT, 0, "关於...");
8 menu.add(0, MENU_Quit, 0, "结束");
9 return true;
10 }
11
12 public boolean onOptionsItemSelected(MenuItem item)
13 {
14 super.onOptionsItemSelected(item);
15 switch(item.getItemId()){
16 case MENU_ABOUT:
17 openOptionsDialog();
18 break;
19 case MENU_Quit:
20 finish();
21 break;
22 }
23 return true;
24 }
每个选单都包含两个部分:
建立选单
处理选项动作
「onCreateOptionsMenu」函式即选单列的主体。在 Android 机器或模拟器上按下硬体的「Menu」(选单)键,所弹出的选单列即是靠「onCreateOptionsMenu」函式来定义。当我们在 Activity 中定义了 「onCreateOptionsMenu」 之后,按下「Menu」(选单)键时,就会弹出相对应的选单列。
当我们在 Android 应用程式的选单列上选择了相应的选项后,则是依赖「onOptionsItemSelected」函式,来负责处理选单列中各选项所个别对应的动作。
在上面的程式裡,我们定义了「关於...」与「结束」两个选单列中的选项。我们分部分讲解如下:
建立选单处理选项动作
在 「onCreateOptionsMenu」函式中,我们定义了两个选单列中的选项。 分行讲解如下:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
return true;
}
「onCreateOptionsMenu」这个函式是选单列的主体,它是一个「public」(公开)的函式。函式传入一个「Menu」(选单)型别的「menu」参数。「boolean」则表示函式的返回值必须為「boolean」型别的值。因此在函式最后,我们提供函式一个返回值「true」。「@Override」表示我们要完全重写掉已定义在「Activity」类别中的这个函式。
基於与 onCreate 函式一样的原因,因為我们把选单列原本的动作覆载 (Override) 掉了,因此在撰写我们自己的内容前,加上一句「super.onCreateOptionsMenu(menu)」叙述,用来呼叫「onCreateOptionsMenu」函式执行预设的动作。
menu.add(0, MENU_ABOUT, 0, "关於...");
menu.add(0, MENU_Quit, 0, "结束");
Android 每个页面对应到一个 Activity,每个 Activity 都有一个独立的选单列。对传入的「menu」参数作处理就能改变选单列的内容。
我们看到,增加一个选单列中选项的格式如下:
menu.add(0, 识别符号(identifer), 0, 字串或资源识别符号);
最后一栏「字串或资源识别符号」就是显示在萤幕上的叙述。 而「识别符号」的目的则是作為这个选项的标籤,以供后续处理选项动作时,更容易辨认出所对应的选项。
protected static final int MENU_ABOUT = Menu.FIRST;
protected static final int MENU_Quit = Menu.FIRST+1;
我们看到 MENU_ABOUT 识别符号的定义,是一个固定的常数型别(static final int)。「Menu.FIRST」则代表识别选单开头的数字,当然我们也可以把这「Menu.FIRST」代号直接用任意数字替换,看看程式会发生什麼事。
在「OptionsItemSelected」函式中,我们分行讲解如下:
public boolean onOptionsItemSelected(MenuItem item)
{
super.onOptionsItemSelected(item);
return true;
}
「onOptionsItemSelected」这个函式是处理所有选项的主体,和「onCreateOptionsMenu」函式相同,也是一个「public」(公开)的函式。「onOptionsItemSelected」函式传入了一个「MenuItem」(选项)型别的「item」参数。「boolean」表示函式的返回值必须為「boolean」型别的值。因此在函式最后,我们提供函式一个返回值「true」。 「super.onOptionsItemSelected(item);」表示我们要先执行已定义在「Activity」类别中原本的「onOptionsItemSelected」函式内容,后面再接著执行我们為此函式新定义的动作。
switch(item.getItemId()){
我们可以用「item.getItemId()」函式来取得在萤幕上选取的选项所对应的识别符号代码(identifer)。
switch(识别符号代码){
....
}
在 swith 叙述中,我们根据从「item.getItemId()」函式取得的识别符号代码判断, 根据选到的识别符号代码,作相应处理。
case MENU_ABOUT:
openOptionsDialog();
break;
case
....
break;
在「onOptionsItemSelected」函式中收到 「MENU_ABOUT」 识别符号时,我们呼叫 「openOptionsDialog」 函式来弹出对话框。
case MENU_Quit:
finish();
break;
在「onOptionsItemSelected」函式中收到 「MENU_Quit」 识别符号时,我们呼叫 Android 内建的 「finish」函式来关闭这个 Activity。因為我们的「BMI」应用程式只由一个「Bmi」Activity 组成,所以当我们呼叫「finish」函式来关闭「Bmi」这个 Activity,就等於直接关闭了这个「BMI」应用程式。
而事实上, 在 Android 平台上,无论是开发者或是使用者,都不需要自己来关闭 Activity。 因為 Android 虚拟机(Dalvik) 接手了什麼时候 Activity 该啟动或关闭的工作。整个 Android Activity 的运作流程,将在后续章节中作讲解。