• 沒有找到結果。

4.12 #12:一個 Activity 啟動另一個 Activity

第 4

Android 應用程式設計

的基礎手藝:12 技

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯

4.1 #1:如何建立 Menu 選單 4.2 #2:如何呈現按鈕(Button)之 1 4.3 #3:如何呈現按鈕(Button)之 2 4.4 #4:如何進行畫面佈局(Layout) 4.5 #5:如何呈現 List 選單之 1 4.6 #6:如何呈現 List 選單之 2

4.7 #7:如何運用相對性佈局(Relative Layout) 4.8 #8:如何運用表格式佈局(Table Layout) 4.9 #9:如何動態變換佈局

4.10 #10:如何定義自己的 View 4.11 #11:如何定義一組 RadioButton

4.12 #12:一個 Activity 啟動另一個 Activity

第 4 章 Android 應用程式設計的基礎手藝:12 技 83

¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

從本章開始,將開始介紹及演練 Android 應用程式開發的基本 36 技了。

其中,有35 技是屬於 Android 框架之上的 Java 程式開發技巧。而第 36 技則屬 於Android 框架之下的 C 程式開發技巧。茲拿麥當勞的漢堡來做比喻,如下圖 所示:

芝麻:Android 應用程式(共 35 技)

上層麵包:Android 框架

牛肉和Cheese:框架與硬體之間 的 C 組件(第 36 技)

底層麵包:硬體組件

併不是 C 組件的技巧較少,而是本書範圍的緣故。本書的主角是「應用

程式開發」,所以偏重於芝麻部份的手藝。筆者的第二本書:「Android 應用

軟體架構設計」,也已經出版了,敬請閱讀之。

這裡以芝麻比喻應用程式,並不是說應用程式的渺小,而表示它的多與 香,若能與起司、牛肉互相搭配,更有特別風味。

在 本 章 裡 , 將 直 接 切 入 應 用 程 式 開 發 的 技 巧 。 如 果 你 還 沒 有 安 裝 過 Android SDK 及其 Eclipse 開發環境的話,請你先閱讀本書附錄-A,其內含:

◆ 如何安裝Android SDK 及其開發環境

◆ 如何著手撰寫Android 應用程式

◆ 如何執行Android 應用程式

如 果 你 覺 得 附 錄-A 還不夠詳細的話,請你上網tom-kao.blogspot.com或 www.misoo1.com 有更詳細的解說。現在就讓我們一起來演練 36 技吧!!

84 Android應用框架原理與程式設計36 技

¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

4.1 #1:如何建立 Menu 選單?

我想大家都很熟悉 Menu 選單的用途了,本節就來說明如何定義 Android 的

Menu 選單,也演練其操作。

4.1.1 操作情境:

1. 此程式開始執行後,按下<MENU>就出現選單如下:

2. 如果選取<Add Item>選項,畫面標題(Title)區顯示出字串:”Insert…”。

3. 再按下<MENU>顯示出選單,如果選取<Del Item>選項,提標(Title)區顯示 出:”Delete…”。

4. 再按下<MENU>顯示出選單,如果選取<Exit>選項,程式就結束了。

4.1.2 撰寫步驟:

Step-1: 建立 Android 專案:ex01。

Step-2: 撰寫 Activity 的子類別:ex01,其程式碼如下:

// ---- ex01.java 程式碼 ---- package com.misoo.ex01;

import android.app.Activity;

import android.os.Bundle;

import android.view.Menu;

import android.view.MenuItem;

public class ex01 extends Activity {

public static final int ADD_ID = Menu.FIRST;

public static final int DELETE_ID = Menu.FIRST + 1;

第 4 章 Android 應用程式設計的基礎手藝:12 技 85

¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

public static final int EXIT_ID = Menu.FIRST + 2;

@Override public void onCreate(Bundle icicle) { super.onCreate(icicle);

setContentView(R.layout.main); }

@Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu);

menu.add(0, ADD_ID, 0, R.string.menu_add);

menu.add(0, DELETE_ID, 1, R.string.menu_delete);

menu.add(0, EXIT_ID, 2, R.string.menu_exit);

return true; }

@Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) {

case ADD_ID: setTitle("Insert..."); break;

case DELETE_ID: setTitle("Delete..."); break;

case EXIT_ID: finish(); break;

}

return super.onOptionsItemSelected(item);

}}

Step-3: 修改/res/values/strings.xml 的內容,更改為:

<?xml version="1.0" encoding="utf-8"?>

<resources>

<string name="app_name">ex01</string>

<string name="menu_add">Add Item</string>

<string name="menu_delete">Del Item</string>

<string name="menu_exit">Exit</string>

</resources>

並儲存之。

Step-4: 執行之。

4.1.3 說明:

1. 一開始,框架就反向呼叫 onCreate()函數,也呼叫 onCreateOptionsMenu()。

2. 當你選取<Add Item>選項時,框架會反向呼叫 onOptionsItemSelected()函數。

3. 框架是主角,ex01 類別只是被呼叫的配角,複雜的控制邏輯都為框架所做掉 了,所以程式碼便得簡單清晰了。

4. 呼叫 onCreate()函數時,此函數首先正向呼叫父類別 Activity 的 onCreate()函 數 , 先 執 行 父 類 別 的 預 設 行 為 , 然 後 才 執 行 ex01::onCreate()函數的附加行

86 Android應用框架原理與程式設計36 技

※ 因為框架的某個函數(不是 Activity::onCreate())呼叫 ex01::onCreate()函數時,

此onCreate()函數無法自己完成整個「create」的任務,而需要父類別的預設函 void paint() { onPaint(); }

Bird

第 4 章 Android 應用程式設計的基礎手藝:12 技 87

¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

式碼就能明瞭了。

// IGraph.java ----介面 public interface IGraph { void onPaint();

public abstract class Shape implements IGraph{

Graphics m_gr;

public class Bird extends Shape { Graphics m_gr;

public Bird(Graphics gr) { super(gr);

m_gr = gr; } public void onPaint(){

super.onPaint();

// 畫圖(海鷗)指令

m_gr.setColor(Color.cyan);

m_gr.drawArc(30,80,90,110,40,100); m_gr.drawArc(88,93,90,100,40,80);

m_gr.setColor(Color.white);

m_gr.drawArc(30,55,90,150,35,75); m_gr.drawArc(90,80,90,90,40,80);

}}

//--- // JMain.java ---- 主程式

import java.awt.*;

import javax.swing.*;

class JP extends JPanel {

public void paintComponent(Graphics gr){

super.paintComponents(gr);

88 Android應用框架原理與程式設計36 技

¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

IGraph cc = new Bird(gr); cc.paint();

}}

public class JMain extends JFrame {

public JMain(){ setTitle(""); setSize(350, 250); } public static void main(String[] args) {

JMain frm = new JMain();

JP panel = new JP();

frm.add(panel);

frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frm.setVisible(true);

}}

此程式畫出兩隻海鷗如下圖:

首先,主程式的指令:cc.paint()呼叫子類別 Bird 的 paint(),但是 Bird 並沒 有 paint()函數,於是採用父類別 Shape 的預設 paint()函數。此預設函數呼叫 onPaint(),就反向呼叫了子類別的 onPaint()。請注意,是父類別 paint()呼叫子類 別的 onPaint();並不是父類別 onPaint()來呼叫子類別的 onPaint()。反而是子類別 onPaint()呼叫父類別的 onPaint()。

4.1.5 補充說明(二):

※ 當你修改/res/values/strings.xml 內容之後,記得要存檔,為什麼呢?因為這樣 可以更新R.java 的內容,讓 menu.add(0, ADD_ID, R.string. menu_add)指令能找 到所要的字串。

※ 請你花一點時間認識一下R.java 的角色和特性,茲說明如下:

第 4 章 Android 應用程式設計的基礎手藝:12 技 89

¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

---- 它(R.java)是連結*.java 的程式碼檔案和*.xml 佈局檔案的中介橋樑。

---- 在 res/layout/裡含有許*.xml 檔案。Eclipse 根據這些.xml 檔內容而自動產 生一個「R」類別(在/src/目錄區裡)。程式師不能用手工去更動它。

---- 當這些.xml 檔案有更新時,Eclipse 就會在你確認並將*.xml 存檔時,自動 更新它(即 R.java 檔案)的內容。

---- 它是程式裡可使用資源(/res/)的索引,對應到*.xml 檔案或字串。讓您的 AP 很方便透過它來取得相關的資源。也就是說,*.java 程式碼透過這索 引 就 能 方 便 地 取 得 所 需 要 的 資 源 。 例 如 , 在 setContentView (R.layout.main) 指 令 裡 的 R.layout.main 就 是 一 個 索 引 項 , 指 引 到 main.xml,就使用了 main.xml 所預設的(Default)陽春型畫面佈局了。