• 沒有找到結果。

畫面操作:

在文檔中 36 應用框架原理與程式設計 (頁 153-164)

動)ac01 類別的物件,並在螢幕上呈現出 ac01_layout 的畫面佈局。

---- 訊息 2:pressPickup()表示使用者從佈局上的 Menu 菜單選取<Pick Up An Item>選項。此刻,ac01 物件立即正向呼叫 Android 框架裡的 startActivity()函 數來誕生(或啟動)pickup 類別(為 Activity 的子類別)的物件,並在螢幕上呈現 出pu_layout 的畫面佈局。

---- 訊息 3:pickUpAnItem()表示使用者從 pu_layout 佈局上的 Menu 選單裡選取一 個 細 項 。 此 刻 ,pickup 物 件 立 即 把 剛 才 選 取 的 細 項 資 料 存 入 框 架 裡 的 SharedPreferences 物件裡面,以便回傳給 ac01 物件。

---- 訊 息 4: pressShowResult()表 示 使 用 者 從 佈 局 上 的 Menu 菜 單 選 取 <Show Result>選項。此刻,ac01 物件立即呼叫 SharedPreferences 物件,從它取得剛

才pickup 物件所寄存的細項資料,然後顯示於畫面上。

6.1.4 畫面操作:

1. 此程式執行時,進入 ac01_layout 畫面佈局。按下<MENU>就出現選單如下:

2. 如果選取<Pick Up An Item>選項,立即切換到 pu_layout 畫面佈局,如下:

3. 按下<MENU>就出現選單如下:

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

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

4. 選取任一個選項之後,立即切換回到 ac01_layout 畫面佈局,如下:

5. 選取<Show Result>選項,就把資料顯示於畫面佈局的 TextView 裡如下:

6. 程式的任務就達成了。

6.1.5 撰寫步驟:

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

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

// ---- ac01.java 程式碼 ----

第 6 章 Use Case 分析的實踐--- 策略-A:6 技 155

public class ac01 extends Activity {

public static final int PICKUP_ID = Menu.FIRST;

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

@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, PICKUP_ID, "Pick Up An Item");

menu.add(1, SHOW_ID, "Show Result"); return true; } @Override

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

case PICKUP_ID:

Intent in = new Intent(ac01.this, pickup.class);

startActivity(in);

return true;

case SHOW_ID:

SharedPreferences passwdfile = getSharedPreferences( "ITEM", 0);

String im = passwdfile.getString("ITEM", null);

TextView tv = (TextView)findViewById(R.id.tv);

tv.setText("choice: " + im);

return true; }

return super.onOptionsItemSelected(item);

}}

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

// ---- pickup.java 程式碼 ---- package com.misoo.ex01_01;

import android.app.Activity;

import android.content.SharedPreferences.Editor;

import android.os.Bundle;

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

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

import android.view.Menu;

public class pickup extends Activity {

public static final int ITEM_1_ID = Menu.FIRST;

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

menu.add(0, ITEM_1_ID, 0, "item-1");

menu.add(0, ITEM_2_ID, 1, "item-2");

menu.add(0, ITEM_3_ID, 2, "item-3");

return true; }

@Override public boolean onOptionsItemSelected(Menu.Item item) { Editor passwdfile = getSharedPreferences("ITEM", 0).edit();

passwdfile.putString("ITEM",item.getTitle().toString());

passwdfile.commit();

Intent in = new Intent(ac01.this, pickup.class);

startActivity(in);

就指名啟動Activity:pickup。

2. pickup 類別裡的指令:

Editor passwdfile = getSharedPreferences("ITEM", 0).edit();

passwdfile.putString("ITEM",item.getTitle().toString());

passwdfile.commit();

finish();

就在呼叫 finish()而於結束此畫面之前,先將 item 的值存入 SharedPreferences 物件裡。

第 6 章 Use Case 分析的實踐--- 策略-A:6 技 157

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

3. 返回到 ac01 的畫面後,指令:

SharedPreferences passwdfile = getSharedPreferences("ITEM", 0);

String im = passwdfile.getString("ITEM", null);

TextView tv = (TextView)findViewById(R.id.tv);

tv.setText("choice: " + im);

就從SharedPreferences 物件取出 item 的值,顯示於畫面的 TextView 上。

6.2 #14: 使用 startActivityForResult() 替代 startActivity()

上一個範例裡,ac01 類別使用 starActivity()函數來啟動 pickup。由於兩個 Activity 通常各在自己的行程(Process)裡執行,不能像傳統呼叫一般函數一樣,直 接回傳資料。而必須透過像 SharedPreferences 等物件間接傳遞。這個方法的好處

是,兩個 Activity 具有高度的獨立性及替代性,更可以獨立發展。在本範例裡,

將採取相依性較大的作法,就是利用 startActivityForResult()函數來啟動另一個 Activity。它的好處是,可以像傳統呼叫一般函數一樣,直接回傳資料。

6.2.1 畫面佈局:

與上一個範例相同,於此省略之。

6.2.2 Activity 類別:

與上一個範例相同,於此省略之。

6.2.3 順序圖:

這個順序圖(Sequence Diagram)與上一範例的順序圖就不一樣了,基於此新

藍圖而寫出的Android 應用程式碼,也就不一樣了。如下圖所示:

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

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

圖6-3 使用 startActivityForResult()時的順序圖

茲說明如下:

---- 訊息 1:create()表示使用者啟動程式時,透過 Android 框架來誕生(或啟 動)ac01 類別的物件,並在螢幕上呈現出 ac01_layout 的畫面佈局。

---- 訊息 2:pressPickup()表示使用者從佈局上的 Menu 菜單選取<Pick Up An Item> 選 項 。 此 刻 , ac01 物 件 立 即 正 向 呼 叫 Android 框 架 裡 的 startActivityForResult()函數來誕生(或啟動)pickup 類別(為 Activity 的子類別) 的物件,並在螢幕上呈現出pu_layout 的畫面佈局。

---- 訊息 3:pickUpAnItem()表示使用者從 pu_layout 佈局上的 Menu 選單裡選取一 個細項。此刻,pickup 物件立即把剛才選取的細項資料回傳給 ac01 物件。

ac01 物件立即顯示於畫面上。

第 6 章 Use Case 分析的實踐--- 策略-A:6 技 159

public class ac01 extends Activity {

public static final int PICKUP_ID = Menu.FIRST;

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

static final int PICKUP_REQUEST = 0;

@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, PICKUP_ID, 0, "Pick Up An Item");

menu.add(1, EXIT_ID, 1, "Exit");

return true; }

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

case PICKUP_ID:

Intent in = new Intent(ac01.this, pickup.class);

startActivityForResult(in,PICKUP_REQUEST);

return true;

case EXIT_ID: finish();

return true;

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

protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == PICKUP_REQUEST) {

if (resultCode == RESULT_CANCELED) setTitle("Canceled...");

else if(resultCode == RESULT_OK) {

TextView tv = (TextView)findViewById(R.id.tv);

String data_str = (String)data.getCharSequenceExtra("DataKey");

tv.setText("choice: " + data_str);

} } }}

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

// ---- pickup.java 程式碼 ----

public class pickup extends Activity {

public static final int ITEM_1_ID = Menu.FIRST;

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

public static final int ITEM_3_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, ITEM_1_ID, 0, "item-1"); menu.add(0, ITEM_2_ID, 1, "item-2");

menu.add(0, ITEM_3_ID, 2, "item-3");

return true; }

@Override public boolean onOptionsItemSelected(MenuItem item) { Bundle bundle = new Bundle();

bundle.putString("DataKey", item.getTitle().toString());

Intent mIntent = new Intent();

第 6 章 Use Case 分析的實踐--- 策略-A:6 技 161

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

mIntent.putExtras(bundle);

setResult(RESULT_OK, mIntent);

finish();

return super.onOptionsItemSelected(item);

}}

Step-4: 執行之。

6.2.6 說明:

1. ac01 類別裡的指令:

Intent in = new Intent(ac01.this, pickup.class);

startActivityForResult (in,PICKUP_REQUEST);

指名啟動Activity:pickup,只是這裡改用 startActivityForResult ()函數而已。

2. pickup 類別裡的指令:

bundle.putString("DataKey", item.getTitle().toString());

Intent mIntent = new Intent();

mIntent.putExtras(bundle);

setResult(RESULT_OK, mIntent);

就在呼叫框架裡的setResult()將 item 值藏於 mIntent 而回傳出去。

3. 返回到 ac01 的畫面後,框架就反向呼叫 ac01 類別的 onActivityResult()函數:

protected void onActivityResult(int requestCode, int resultCode, String data, Bundle extras) { //………..

}

其中參數data 就含有剛才回傳的 item 值了。

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

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

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

// --- ac01.java 程式碼 --- // 這個 ac01 類別的程式與上一個範例(第 6.2.5 節)的 ac01.java 內容完全一樣,

由於篇幅的限制,於此省略之。

//--- Step-3: 撰寫 Activity 的子類別:pickup,其程式碼如下:

// ---- pickup.java 程式碼 ----

第 6 章 Use Case 分析的實踐--- 策略-A:6 技 163

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

import android.widget.SimpleAdapter;

import android.widget.AdapterView.OnItemClickListener;

public class pickup extends Activity { private ListView lv;

private Map<String, Object> item;

private List<Map<String, Object>> coll;

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

lv.setAdapter(adapter); lv.setOnItemClickListener(listener);

setContentView(lv); }

OnItemClickListener listener = new OnItemClickListener() {

public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { String str = coll.get(arg2).get("price").toString();

Bundle bundle = new Bundle(); bundle.putString("DataKey", str);

Intent mIntent = new Intent(); mIntent.putExtras(bundle);

setResult(RESULT_OK, mIntent);

finish();

}};

protected void addData() {

item = new HashMap<String, Object>();

item.put("title", "Item-1"); item.put("price", "US$50"); coll.add(item);

item = new HashMap<String, Object>();

item.put("title", "Item-2"); item.put("price", "US$800"); coll.add(item);

item = new HashMap<String, Object>();

item.put("title", "Item-3"); item.put("price", "US$777"); coll.add(item);

}}

Step-4: 執行之。

6.3.4 說明:

1. 在本書的第 4 章裡,已經使用過 ListView 了。於此,只是複習及活用它來銜接 Use Case 分析,來實踐它。

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

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

在文檔中 36 應用框架原理與程式設計 (頁 153-164)