Upload
winifred-kathlyn-hunt
View
233
Download
0
Embed Size (px)
Citation preview
Target UserTarget User 想節省開發時間的使用者 想專注在 App 功能設計的創業家 Framework 愛好者 Design Pattern 擁護者 討厭 XML 排版的人 愛用國貨的支持者
FeaturesFeaturesObject-Relational Mapping(ORM)Predefined ActionsNew Layout MechanismEnhanced ActivitySimple Dialog ModelSimple AdapterUI Data PersistanceUsable Service JSON-Java ConverterHTTP POSTActivity-Phase Broadcast HandlingAnimate Effect
Sample App –Sample App – 「我的書庫」「我的書庫」設計功能
◦ 可新增書籍◦ 提供書本的清單◦ 提供單本書的檢視◦ 書籍提供「借出」及
「歸還」功能
特色◦ 以 CodeScanner 掃描
ISBN 碼◦ 自動尋找書本封面圖片◦ 可設定每本書的閱讀進度
Object-Relational MappingObject-Relational Mapping◦ 新增資料
◦ 刪除資料
◦ 修改資料
◦ 查詢資料
◦ 產生 Table
helper.insert(book);
helper.delete(book.get_id());
helper.update(book);
List<Book> books = helper.select();List<Book> books = helper.select(“where status=1”);Book book = helper.selectSingle(“where _id=1”);
GenericHelper helper = new GenericHelper(new FaceData(…), Book.class);
換頁換頁new GoAction(context,
Page.class).execute();
new GoAction(context, Page.class).setSubTask(0).execute();
通知通知 (Notification)(Notification)new NotifyAction(context).setTitle(“ 新訊息” ) .setContent(“ 你被邀請加入一個社
團” ).execute();
對話方塊對話方塊new AlertAction(context).setData(“ 系統” ,“ 你有一篇未完成的草稿,是否要繼續編輯 ?” ,new
GoAction(context,” 是” ,ActivityEditor.class) ,new
GoAction(context,” 否” ,ActivityMain.class)).execute();
自定義自定義 ActionActionnew Action(){
public boolean execute(){}
}
new ContextAction(context){public boolean execute(Context context){}
}
new ThreadAction(context,0){public boolean execute(Context context){}
}
如何做出以下的排版如何做出以下的排版 ??RL LL
Button
SV
Button
Button
TextView
TextView
ImageView
ImageView
Button
TextView
Grandroid Layout ConceptGrandroid Layout Concept
1. 使用 LayoutMaker 物件2. RelativeLayout 、 ScrollView 會自
動產生3. 每生成一個 Panel ,需要執行跳脫,
才能回到父 Panel4. 一行程式碼 = 一個 Layout 動作
Example 1Example 1LinearLayout
Text1
Button
Text2
@Overridepublic void onCreate(Bundle bundle) { super.onCreate(bundle);
LayoutMaker m = new LayoutMaker(this);
m.addTextView(“Text1”);
m.add(m.createTextView(“Text2”),m.layFW(1));
m.add(maker.createButton(“Button”),m.layFW(0));
}
Tip: addXXX() = createXXX + add()
LayoutMaker MethodsLayoutMaker MethodsCreate View Create & Add
ViewCreate & Enter Panel
Others
createTextView addTextView addTopBanner escape
createButton addButton addBottomBanner
add
createImage addImage addRowLayout layWW
createSpinner addSpinner addColLayout layFF
createListView addListView layFW
createCheckBox addCheckBox layWF
createEditText addEditText getLastLayout
createRadioGroup
addRadioGroup getRootLayout
Example 2 (1/7)Example 2 (1/7)LL
LayoutMaker m = new LayoutMaker(this);
m.addTopBanner();
m.addTextView(“Text1”);
m.addButton(“Button1”);
m.escape();
m.addBottomBanner();
m.addButton(“Button2”);
m.escape();
m.add(m.createTextView(“Text2”),m.layFF());
RL
Text1 Button1
Button2
Text2
Example 2 (3/7)Example 2 (3/7)LL
LayoutMaker m = new LayoutMaker(this);
m.addTopBanner();
RL Last Layout
Example 2 (4/7)Example 2 (4/7)LL
LayoutMaker m = new LayoutMaker(this);
m.addTopBanner();
m.addTextView(“Text1”);
m.addButton(“Button1”);
RL
Text1 Button1
Last Layout
Example 2 (5/7)Example 2 (5/7)LL
LayoutMaker m = new LayoutMaker(this);
m.addTopBanner();
m.addTextView(“Text1”);
m.addButton(“Button1”);
m.escape();
RL
Text1 Button1
Last Layout
Example 2 (6/7)Example 2 (6/7)LL
LayoutMaker m = new LayoutMaker(this);
m.addTopBanner();
m.addTextView(“Text1”);
m.addButton(“Button1”);
m.escape();
m.addBottomBanner();
m.addButton(“Button2”);
m.escape();
RL
Text1 Button1
Button2
Last Layout
Example 2 (7/7)Example 2 (7/7)LL
LayoutMaker m = new LayoutMaker(this);
m.addTopBanner();
m.addTextView(“Text1”);
m.addButton(“Button1”);
m.escape();
m.addBottomBanner();
m.addButton(“Button2”);
m.escape();
m.add(m.createTextView(“Text2”),m.layFF());
RL
Text1 Button1
Button2
Text2
Last Layout
Enhanced ActivityEnhanced Activity• Activity 改繼承 Face 類別• 新增 Menu• 載入 layout xml 元件• 挑選日期或時間• 挑選命令• 收聽事件廣播• 設定按鈕事件
輸入對話方塊輸入對話方塊 new InputDialogMask(this, “ 系統” , “”, “ 請輸入
密碼 ", null) { @Override public boolean executeAction(String
string) { //handle user input return true; } }.show();
客製化對話方塊客製化對話方塊new DialogMask(this) {
@Override
public boolean setupMask(Context c, Builder builder, LayoutMaker maker) throws Exception {
((LinearLayout) maker.getLastLayout()).setGravity(Gravity.CENTER_HORIZONTAL);
maker.addTextView(" 你的朋友欠你書一個月了 ! 是否要提醒他還書 ?").setPadding(5, 5, 5, 5);
Book book = helper.selectSingle(5);
maker.addImage(ImageView.class, book.getPath());
maker.add(maker.createTextView(" 就是這本 !"), maker.layFW()).setGravity(Gravity.CENTER);
builder.setTitle(" 提醒 ");
builder.setPositiveButton(new DialAction(c, " 打電話 "));
builder.setNegativeButton(new Action(" 寄信 "));
return true;
}
}.show();
Simple AdapterSimple Adapter• ObjectAdapter
• Base on List<Object>
• FaceDataAdapter• Base on SQL
• JSONAdapter• Base on JSONArray
ObjectAdapterObjectAdapterList<Book> books = new GenericHelper<Book>(new FaceData(c,
“db"), Book.class).select();
maker.addListView(new ObjectAdapter<Book>(this, books) {
@Override
public View createRowView(int i, Book t) {
}
@Override
public void fillRowView(int i, View view, Book t) {
}
@Override
public void onClickItem(int index, View view, Book item) {
}
@Override
public void onLongPressItem(int index, View view, Book item) {
}
});
FaceDataAdapterFaceDataAdapterGenericHelper helper = new GenericHelper(new FaceData(this, "db"),
Book.class);
maker.addListView(new FaceDataAdapter<Book>(this, helper, "where status=1", false) {
@Override
public View createRowView(int i, Book t) {
}
@Override
public void fillRowView(int i, View view, Book t) {
}
@Override
public void onClickItem(int index, View view, Book item) {
}
@Override
public void onLongPressItem(int index, View view, Book item) {
}
});
JSONAdapterJSONAdapterJSONArray array = new
Mon("http://someweb/api").sendAndWrapArray();
maker.addListView(new JSONAdapter(this,array) {
@Override
public View createRowView(int i, JSONObject jo) {
}
@Override
public void fillRowView(int i, View view, JSONObject jo) {
}
@Override
public void onClickItem(int index, View view, JSONObject jo) {
}
@Override
public void onLongPressItem(int index, View view, JSONObject jo) {
}
});
JSON-Java ConverterJSON-Java Converter
//Java to JSON JSONObject jo = new
JSONConverter().fromObject(book);
//JSON to JavaBook book = new
JSONConverter().toObject(jo, Book.class);
HTTP POSTHTTP POST// 取得 server 回傳字串String content = new
Mon(url).put(“uid”,uid).send();
// 取得 server 回傳 JSONObjectJSONObject jo = new
Mon(url).put(“uid”,uid).sendAndWrap();
// 取得 server 回傳 JSONArrayJSONArray ja = new
Mon(url).put(“uid”,uid).sendAndWrapArray();
Activity-Phase Broadcast Activity-Phase Broadcast HandlingHandling
如何設計一個這樣的情境:◦背景上傳照片◦上傳完畢之後立刻顯示於目前畫面◦若使用者沒有正在使用 App ,顯示通知
(Notification)◦上傳過程中使用者可能切換到別的頁面
Sample CodeSample Code在 Face 裡捕捉 UPLOAD_DONE 事件 :registerBundledAction("UPLOAD_DONE", new
ShowImageAction(...));
在 Service 裡設計if(AppStatus.ON_TOP) { Intent intent = new Intent(); intent.setAction(“UPLOAD_DONE”); this.sendBroadcast(intent);}else{ new NotifyAction(this).setContent("title", "content").setGroup(0) .setAutoCancel(true).setIcon(R.drawable.icon).execute();}
註: UPLOAD_DONE 需先於 AndroidManifest.xml 中宣告
Other UtilitiesOther Utilities• ImageUtil
◦ 快速載入、縮放、裁切、疊合圖片• LayoutUtil
◦ 取得螢幕寬高及真正的解析度• GPSUtil
◦ 快速取得最後已知的位置及重新定位• UserUtil
◦ 快速取得使用者所有帳號及聯絡人• PhoneUtil
◦ 取得網路狀態及手機硬體 ID
Grandroid Family LibrariesGrandroid Family Libraries• Facepaper
• 整合 Facebook Library ,提供更簡單的介面• Grangeo
• 提供 GeoFace 及地理方面的功能• Gransfer
• 提供更容易上傳、下載檔案及 Cache 圖片的方法• Gramara
• 提供 CameraFace 、處理已知硬體 Bug ,並提供更更易用的介面
• Raingo• 封裝 MongoDB ,提供簡便的 CRUD Servlet