動)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 技
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯