5.2 Android 平台專屬導引精靈
5.2.2 Android 導引精靈的轉換
MoDWizII 系統是以 Eclipse 為平台做以下三種精靈程式的開發,Java 導引精靈程 式、Eclipse 導引精靈程式和 Web 導引精靈程式,系統主要開發工具是 EMF、Xtend 和 Xtext,透過 EMF 建置模型框架和原始碼產生,並以 XMI 描述模型規格產生基本的編譯 器,所有會使用到的導引精靈元件和框架則以 Xtext 定義,再透過 Xtend 處理相關的轉
‧
在第一次轉換(M2M)的過程中,我們從 iwiz 文件中分離出來的資訊轉換到 Android 平台專屬的系統上,所轉換的資訊如下所示:
• 系統名稱(IWizard-> AWizard)、
• 頁面名稱(IPageName-> APageName)、
• 頁面執行順序(IPageList-> APageList、IpageSeq-> APageSeq)、
• 頁面內容(IPage-> APage)、
• 分支預測(IBranches-> ABranches、ICondition-> ACondition)、
• 問題類型(SingleQuestion、GroupQuestion、TextInput、Dialog-> AComponentSet)、
• 元件(textfield、textarea、radio、check、dropdown、filebrowser-> AComponent)、
• 選單項目(MenuItem-> Item)、
• 欄位驗證(Validation-> AValidation)。
再透過第二次轉換(M2T)而得到 Android 平台專屬的程式碼,例如表 5-1 所示。
表 5-1:TextField 的轉換(上半部為轉換的實作,下半部為產生的結果)。
«IF componentset.type == "TextField"»
<LinearLayout style="@style/WizardLayoutStyle">
<TextView
style="@style/WizardFormLabel"
android:text=
"«(componentset.components.get(0) as ATextView).text»"/>
«IF componentset.components.get(1) instanceof AEditText»
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textCapWords"
android:id="@+id/«"your_"+
‧
(componentset.components.get(1) as AeditText).name»"/>
«ENDIF»
</LinearLayout>
<!--- Textfield Components -->
<LinearLayout style="@style/WizardLayoutStyle">
<TextView
style="@style/WizardFormLabel"
android:text="First Name:"/>
<EditText
android:layout_width="match_parent" 方法是修改官方 SDK 中 Fragment 實作的內容,將原本 android-support-v4.jar 函式庫內 DEFAULT_OFFSCREEN_PAGES=1 的預設值改成 0 並重新編譯後即可解決此預載頁面 的問題。在動態條件分支的設計上,我們在分支頁面上加入 Branch 的建構式(如表 5-2 所示),並給定 addBranch 的方法使分支頁面能夠透過 addBranch 加入子頁面,如此一來 既不需要重新產生 Branch Page 也不需要重新建立 Branch 與 Page 之間的鏈結關係。
表 5-2:Branch 建構式。
public Page4 addBranch(String choice, Page...childPages) {
PageList childPageList = new PageList(childPages);
for (Page page : childPageList) { page.setParentKey(choice);
}
mBranches.add(new Branch(choice, childPageList));
return this;
‧
private static class Branch {
public String choice;
public PageList childPageList;
private Branch(String choice,PageList childPageList) {
this.choice = choice;
this.childPageList = childPageList;
} }
然而資料驗證和傳遞則透過 PageFragment 中元件選擇後的反應來觸發該驗證結果 並回傳資料(如表 5-3 所示),在 If 條件中,由於我們在每個元件執行完時會執行 mPage.getData().putString(String key, String value)的方法,目的是將該元件的名稱和對應 的值放入預先定義好的 Map 中(如表 5-4 所示),最後透過 mPage.getData().getString(String key)的方法擷取出某頁面的值作為判斷的條件,條件成立之後便決定了分支後的結果。
表 5-3:分支條件驗證和回傳。
marriage.setOnItemSelectedListener(
new OnItemSelectedListener(){
@Override
public void onItemSelected(AdapterView<?> parent,View view,int position, long id){
Page.getData().putString( Page4.showmarriage, marriage.getSelectedItem().toString());
‧ 國
立 政 治 大 學
‧
N a tio na
l C h engchi U ni ve rs it y
60
&&mPage.getData().getString(Page4.showmarriage).equals(
"Married"))
mPage.getData().putString(Page4.showmbranch,"2");
else
mPage.getData().putString(Page4.showmbranch,"3");
mPage.notifyDataChanged();
}
@Override
public void onNothingSelected(AdapterView<?> parent) {}
});
表 5-4:Map 結構。
public static Page4Fragment create(String key) { Bundle args = new Bundle();
args.putString(ARG_KEY, key);
Page4Fragment fragment = new Page4Fragment();
fragment.setArguments(args);
return fragment;
}
最後在回顧頁面(Review)時會將先前使用者輸入的資訊從 ArrayList<ReviewItem>中 擷取出來,藉由表 5-5 定義 ReviewItem 的類別和方法,其方法分別實作了 getTitle()和 getDisplayValue(),目的是透過 ListView 的排版方式顯示顯示循序印出每一頁存入的 Title 和 DisplayValue 這兩個值(顯示結果如圖 5-6 所示),最後主程式觸發 Review 的判斷條 件,進而呼叫 ReviewFragment 並列出相關回顧資料(如表 5-6 所示)。
‧
public void getReviewItems(ArrayList<ReviewItem> dest) {dest.add(new ReviewItem("First Name:",
mData.getString(first_DATA_KEY), getKey(), -1));
dest.add(new ReviewItem("Last Name:",
mData.getString(last_DATA_KEY), getKey(), -1));
dest.add(new ReviewItem("Your Email:",
mData.getString(email_DATA_KEY), getKey(), -1));
dest.add(new ReviewItem("Re-enter Email:",
mData.getString(re_email_DATA_KEY), getKey(), -1));
dest.add(new ReviewItem("New Password:(input 6~8 characters or numbers)",
mData.getString(password_DATA_KEY), getKey(), -1));}
public ReviewItem(String title, String displayValue, String pageKey, int weight) {
mTitle = title;
mDisplayValue = displayValue;
mPageKey = pageKey;
mWeight = weight;
}
public void setDisplayValue(String displayValue) { mDisplayValue = displayValue;
}
public String getTitle() { return mTitle;}
public Fragment getItem(int i) {
if (i >= mCurrentPageSequence.size()) { return new ReviewFragment();
}
Return mCurrentPageSequence.get(i).createFragment();}
‧ 國
立 政 治 大 學
‧
N a tio na
l C h engchi U ni ve rs it y
62
圖 5-6:Review 顯示。