Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

20130614 Titanium簡介@政大資科

2,911 views

Published on

Published in: Technology, Art & Photos
  • Be the first to comment

20130614 Titanium簡介@政大資科

  1. 1. Titanium Mobile簡介李易修用Javascript打造原生行動應用程式
  2. 2. 李易修 (阿修)• 旅⼈人⼀一番 UX Lead & Co-funder• 台灣使⽤用者經驗設計協會(UiGathering)創會成員及理事• http://www.lis186.com• twitter: lis186
  3. 3. Titanium的javascript環境沒有DOM,不用JQuery所有的UI由Javascript建立window相當於瀏覽器視窗view相當於div事件處理同樣是用AddEventListener維持一個execution context
  4. 4. 牛刀小試Hello World! Titanium
  5. 5. HowIsTheWeather/build/android/...iphone/...CHANGELOG.txtLICENSELICENSE.txtmanifestREADMEResources/android/...app.jsiphone/...KS_nav_ui.pngKS_nav_views.pngtiapp.xml檔案及目錄結構原生專案起始檔設定檔android專用檔案iphone專用檔案原始碼和其他資料檔
  6. 6. var win = Titanium.UI.createWindow({backgroundColor:#fff});var label = Titanium.UI.createLabel({text: Hello World!,textAlign: center});label.addEventListener(click, function(e){Titanium.API.info(label clicked!);});win.add(label);win.open();Hello World!
  7. 7. http://www.tisnippet.com/
  8. 8. UI元件的使用
  9. 9. Titanium.UI.TabGroup共有的元件
  10. 10. 特有的元件Titanium.UI.iPad.Popover
  11. 11. 模擬特有的元件TabbedBar Button
  12. 12. 區分不同裝置Titanium.Platform.osname//iphone, ipad, androidTitanium.Platform.version
  13. 13. 為不同螢幕最佳化
  14. 14. 解析度(Resolution)320x480240x320480x800480x8541280x800240x400240x432320x480640x960768x102
  15. 15. 密度(Density)http://www.engadget.com/2010/06/22/iphone-4-review/
  16. 16. Retina Display
  17. 17. 為不同螢幕準備素材normalretina hdpiAndroidmdpildpiiOS
  18. 18. 從大做到小
  19. 19. 為不同螢幕準備素材Starred.pngStarred@2x.pngiOSAndroid⽤用檔名區分⽤用路徑區分res-long-port-hdpires-long-port-mdpires-long-port-ldpi
  20. 20. 長度單位var view = Titanium.UI.createView({width: 100, //Pixelheight: 100dp,//Density independence});win.add(view);win.open();
  21. 21. 處理不同方向Titanium.Gesture.addEventListener(orientationchange, function (e) {switchLayout(e.orientation);});
  22. 22. http://goo.gl/0be5C
  23. 23. Titanium開發實戰現在天氣怎麼樣?
  24. 24. 功能:顯示這裡現在的天氣你可以學到:建⽴立UI取得GPS資訊讀取遠端資料儲存資訊顯⽰示網⾴頁使⽤用各平台特有功能現在天氣怎麼樣?原始碼:http://goo.gl/Fj3pl
  25. 25. var win = Titanium.UI.createWindow({backgroundColor:#fff});var locationLabel = Titanium.UI.createLabel({color:#000,text:內湖區,font:{fontSize: 30, fontFamily:Helvetica Neue},textAlign:center,width:auto,height: auto,left: 15,top: 75});var weatherIcon = Titanium.UI.createImageView({image: images/mostly_cloudy.gif,width: 80,height: 80,left: 15,top: 120});建立UI75px15px絕對定位
  26. 26. var temperatureLabel = Titanium.UI.createLabel({color:#000,text:28°C,font:{fontSize: 90, fontFamily:Helvetica Neue},textAlign:center,width:auto,height: auto,right: 15,top: 100});var detailLabel = Titanium.UI.createLabel({color:#000,text: 多雲時陰n濕度: 62%n⾵風向: ⻄西北n⾵風速:10 公⾥里/⼩小時,font:{fontSize: 24, fontFamily:Helvetica Neue},textAlign:left,width:auto,height: auto,left: 20,top: 220});win.add(locationLabel);win.add(weatherIcon);win.add(temperatureLabel);win.add(detailLabel);win.open();建立UI (續)
  27. 27. if (Titanium.Geolocation.locationServicesEnabled === false){Titanium.UI.createAlertDialog({title:無法使⽤用定位服務,message:請開啓定位服務,這樣才能取得現在位置的天氣。}).show();}else{Ti.Geolocation.purpose = "get current position";Titanium.Geolocation.accuracy = Titanium.Geolocation.ACCURACY_THREE_KILOMETERS;Titanium.Geolocation.distanceFilter = 1000;Titanium.Geolocation.getCurrentPosition(function(e){if (e.error){Titanium.API.info("error: " + JSON.stringify(e.error));return;}var latitude = e.coords.latitude;var longitude = e.coords.longitude;Ti.API.info(longitude+,+latitude);});...}取得經緯度座標iOS 3.2以上需要這行。取座標
  28. 28. function updateLocationName(lat, lng){Titanium.Geolocation.reverseGeocoder(lat, lng, function(e){if (e.success) {var places = e.places;if (places && places.length) {locationLabel.text = places[0].city;} else {locationLabel.text = "";}Ti.API.debug("reverse geolocation result = "+JSON.stringify(e));}else {Ti.UI.createAlertDialog({title:Reverse geo error,message:evt.error}).show();Ti.API.info("Code translation: "+translateErrorCode(e.code));}});}更新地名利用座標查詢地址
  29. 29. http://api.worldweatheronline.com/free/v1/weather.ashx?key={api_key}&q={latitude},{longitude}&format=jsonWorld Weather Online APIhttp://www.worldweatheronline.com/free-weather.aspx{"data":{"current_condition":[{"cloudcover":"75","humidity":"94","observation_time":"12:09 AM","precipMM":"0.0","pressure":"1004","temp_C":"24","temp_F":"75","visibility":"5","weatherCode":"353","weatherDesc":[{"value":"Light rain shower"}],"weatherIconUrl":[{"value":"http://www.worldweatheronline.com/images/wsymbols01_png_64/wsymbol_0009_light_rain_showers.png"}],"winddir16Point":"ESE","winddirDegree":"110","windspeedKmph":"7","windspeedMiles":"4"}],
  30. 30. 更新天氣function updateWeather(lat, lng){if(PlatformOS === android){indicator.message = 讀取天氣資訊中;}indicator.show();var xhr = Titanium.Network.createHTTPClient();xhr.onload = function(){indicator.hide();var data = JSON.parse(this.responseText).data;Ti.API.info(data);};api_key = x5rdbt7d466du33m3rngxs2c;var url = http://api.worldweatheronline.com/free/v1/weather.ashx?key=+api_key+&format=json&q=+lat+,+lng;Ti.API.info(url);xhr.open(GET, url);xhr.send();}
  31. 31. 更新天氣xhr.onload = function(){indicator.hide();var data = JSON.parse(this.responseText).data;var condition = data.current_condition[0].weatherDesc[0].value;var temp_f = data.current_condition[0].temp_F;var temp_c = data.current_condition[0].temp_C;var icon = data.current_condition[0].weatherIconUrl[0].value;var humidity = data.current_condition[0].humidity;var tempUnit = Titanium.App.Properties.getString(tempUnit, c);if(tempUnit === c){temperatureLabel.text = temp_c + °C;if(PlatformOS === iphone || PlatformOS === ipad){Titanium.UI.iPhone.appBadge = temp_c;}}else if(tempUnit === f){temperatureLabel.text = temp_f + °F;if(PlatformOS === iphone || PlatformOS === ipad){Titanium.UI.iPhone.appBadge = temp_f;}}weatherIcon.image = icon;detailLabel.text = condition + n;detailLabel.text += humidity + n;};
  32. 32. 包裝一下function getCurrentWeather(){if (Titanium.Geolocation.locationServicesEnabled === false){Titanium.UI.createAlertDialog({title:無法使⽤用定位服務, message:請開啓定位服務,這樣才能取得現在位置的天氣。}).show();}else{Ti.Geolocation.purpose = "取得⺫⽬目前位置的天氣資訊";Titanium.Geolocation.accuracy = Titanium.Geolocation.ACCURACY_BEST;Titanium.Geolocation.distanceFilter = 1000;Titanium.Geolocation.getCurrentPosition(function(e){if (e.error){Titanium.API.info("error: " + JSON.stringify(e.error));Titanium.UI.createAlertDialog({title:無法取得位置資訊, message: e.error.message}).show();detailLabel.text = 無法取得⺫⽬目前位置的天氣資訊,請稍候再試。;return;}var latitude = e.coords.latitude;var longitude = e.coords.longitude;Ti.API.info(longitude+,+latitude);updateLocationName(latitude, longitude);updateWeather(latitude, longitude);});}}
  33. 33. getCurrentWeather();updateInterval = setInterval(getCurrentWeather, 300000);每五分鐘更新一次別忘了第一次
  34. 34. 建立設定頁面—相同的部份var settingWin = Titanium.UI.createWindow({backgroundColor: #999});var aboutWebview = Titanium.UI.createWebView({url: about.html,...});settingWin.add(aboutWebview);var doneButton = Titanium.UI.createButton({title: 完成,...});settingWin.add(doneButton);doneButton.addEventListener(click, function(e){if(Titanium.Platform.osname === iphone){settingWin.close({transition: Ti.UI.iPhone.AnimationStyle.FLIP_FROM_RIGHT});mainWin.open();}else if(Titanium.Platform.osname === android){mainWin.open();settingWin.close();}getCurrentWeather();});iOS內建特效依平台不同調整轉場效果
  35. 35. <!doctype html><html lang="zh-tw"><head><meta charset="utf-8"><title>About</title><meta name="description" content="About the app"><meta name="viewport" content="width=320"/><meta name="author" content="lis186"><link rel="stylesheet" href="screen.css"></head><body><h1>現在天氣怎麼樣</h1><img src=appicon.png><p>版本 1.0</p><p>Powered by Titanium Mobile.</p></body></html>about.js用WebView來簡化文字段落編排
  36. 36. 建立設定頁面—iPhone部份if(Titanium.Platform.osname === iphone){var unitTabbedBar = Titanium.UI.createTabbedBar({labels:[°C, °F],style:Titanium.UI.iPhone.SystemButtonStyle.BAR,...});unitTabbedBar.addEventListener(click, function(e){if(e.index === 0){Titanium.App.Properties.setString(tempUnit, c);}else if (e.index === 1){Titanium.App.Properties.setString(tempUnit, f);}});settingWin.add(unitTabbedBar);var settingButton = Titanium.UI.createButton({...style: Titanium.UI.iPhone.SystemButton.INFO_DARK});mainWin.add(settingButton);}iOS系統按鈕
  37. 37. 建立設定頁面—Android部份if(Titanium.Platform.osname === android){var cButton = Titanium.UI.createButton({title: °C,...});var fButton = Titanium.UI.createButton({title: °F,...});cButton.addEventListener(click, function(e){Titanium.App.Properties.setString(tempUnit, c);cButton.enabled = false;fButton.enabled = true;});fButton.addEventListener(click, function(e){Titanium.App.Properties.setString(tempUnit, f);cButton.enabled = true;fButton.enabled = false;});settingWin.add(cButton);settingWin.add(fButton);}
  38. 38. 依照平台UI慣例切換頁面—iPhone部份if(Titanium.Platform.osname === iphone){mainWin.add(settingButton);settingButton.addEventListener(click, function(e){settingWin.open({transition: Ti.UI.iPhone.AnimationStyle.FLIP_FROM_LEFT});var tempUnit = Titanium.App.Properties.getString(tempUnit, c);if(tempUnit === c){unitTabbedBar.index = 0;}else if(tempUnit === f){unitTabbedBar.index = 1;}mainWin.close();});}iOS內建特效利用Property儲存溫度單位
  39. 39. 依照平台UI慣例切換頁面—Android部份if(Titanium.Platform.osname === android){Titanium.Android.currentActivity.onCreateOptionsMenu = function(e) {Titanium.API.info("create menu");var menu = e.menu;var refreshMenuItem = menu.add({ title: 更新天氣 });var settingMenuItem = menu.add({ title: 設定 });refreshMenuItem.addEventListener("click", function(e) {getCurrentWeather();});settingMenuItem.addEventListener("click", function(e) {indicator.hide();settingWin.open();var tempUnit = Titanium.App.Properties.getString(tempUnit, c);if(tempUnit === c){cButton.enabled = false;fButton.enabled = true;}else if(tempUnit === f){cButton.enabled = true;fButton.enabled = false;}mainWin.close();});};}
  40. 40. if(Titanium.Platform.osname === iphone){var service;Titanium.App.addEventListener(pause,function(e){Ti.API.info(pause);service = Titanium.App.iOS.registerBackgroundService({url: bgjob.js,tempUnit: Titanium.App.Properties.getString(tempUnit, c)});Titanium.API.info("registered background service = "+service);});Titanium.App.addEventListener(resumed,function(e){Ti.API.info(resumed);if(service != null){getCurrentWeather();service.stop();service.unregister();Ti.API.info(Stop background service);}});}利用iOS background service更新badgecustom property
  41. 41. function updateWeather(lat, lng){var xhr = Titanium.Network.createHTTPClient();xhr.onload = function(){var tempUnit = Titanium.App.currentService.tempUnit;...if(tempUnit === c){Titanium.UI.iPhone.appBadge = temp_c;Ti.API.info(Update badge: + temp_c);}else if(tempUnit === f){Titanium.UI.iPhone.appBadge = temp_f;Ti.API.info(Update badge: + temp_f);}};var url = http://www.google.com/ig/api?hl=zh-tw&weather=,,,+parseInt(lat*1000000, 10)+,+parseInt(lng*1000000, 10);Ti.API.info(url);xhr.open(GET, url);xhr.send();}function getCurrentWeather(){...}...Ti.API.info(starting background service);var updateInterval = setInterval(getCurrentWeather, 300000);bgjob.jscustom property
  42. 42. if(Titanium.Platform.osname === android){Titanium.Android.currentActivity.addEventListener(resume, function(e) {Ti.API.info("resumed");getCurrentWeather();});}Android從背景resume後更新天氣
  43. 43. 結論
  44. 44. 跨平台 !== “Write Once, Run Everywhere”別忘了為各平台最佳化
  45. 45. 有了好工具,仍然需要好點子http://www.cultofmac.com/self-evidently-bad-app-idea-scale-for-ipad
  46. 46. http://goo.gl/Fj3pl範例:現在天氣怎麼樣Kitchen Sinkhttp://goo.gl/5v6dJ
  47. 47. 謝謝!

×