20130614 Titanium簡介@政大資科
- 2. 李易修 (阿修)
• 旅⼈人⼀一番 UX Lead & Co-funder
• 台灣使⽤用者經驗設計協會(UiGathering)
創會成員及理事
• http://www.lis186.com
• twitter: lis186
- 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!
- 20. 長度單位
var view = Titanium.UI.createView({
width: 100, //Pixel
height: '100dp',//Density independence
});
win.add(view);
win.open();
- 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
});
建立UI
75px
15px
絕對定位
- 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. 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. 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. http://api.worldweatheronline.com/free/v1/weather.ashx?
key={api_key}&q={latitude},{longitude}&format=json
World Weather Online API
http://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. 更新天氣
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. 更新天氣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. 包裝一下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);
});
}
}
- 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. <!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. 建立設定頁面—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. 建立設定頁面—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);
}
- 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. 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更新badge
custom property
- 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.js
custom property