2012年7月1日 星期日
Titanium 背景開啟webview
資料來源
http://developer.appcelerator.com/question/22871/how-to-start-the-app-then-render-html-in-background-then-show-it
基本作法
加入webview時,設定visible = fasle
然後加入load事件動作: 設定 visiable=true
這作法有個副作用是webview在顯示時會保存一開始設定網頁狀態,不會自動重新讀取,
除非跳離window或要求更新
code:
var webView = Titanium.UI.createWebView({url:'index.html', visible:false});
webView.addEventListener('load', function() { webView.visible = true; });
2012年6月21日 星期四
Titanium 動畫與view的關係
Titanium on iOS上,有提供動畫功能
不過有些view本身是不合適動態改變大小的
例如webview..
例如以下情況
viewA.top=0;
viewA.height=50;
viewA.animate({top: 100, height:200});
如果viewA是mapview,動畫效果會包括從0移動到100, 同時尺寸會從50成長為200
但viewA是web view時,動畫效果是viewA從50立刻變成200, 同時會從0移動到100
因此在使用動畫時,要注意viewA的類別是否為可動態改變大小的view
因為這問題,在處理時會需要考慮作法:如何讓動畫顯示的順暢
題外話:
同事比較偏好這作法
不過有些view本身是不合適動態改變大小的
例如webview..
例如以下情況
viewA.top=0;
viewA.height=50;
viewA.animate({top: 100, height:200});
如果viewA是mapview,動畫效果會包括從0移動到100, 同時尺寸會從50成長為200
但viewA是web view時,動畫效果是viewA從50立刻變成200, 同時會從0移動到100
因此在使用動畫時,要注意viewA的類別是否為可動態改變大小的view
因為這問題,在處理時會需要考慮作法:如何讓動畫顯示的順暢
題外話:
同事比較偏好這作法
2012年6月19日 星期二
titanium table data在android上取用問題
在android上註冊table事件並取用資料,如e.source時
有時會有null問題
後來發現問題在於data item的設定方法
var dataitem= Ti.UI.createTableCellView({
aa: '123'
});
dataitem.bb = '456';
在這寫法下,取得e.aa不會有問題
取得e.bb則會有10%成功機會
簡單來說就是把已知、必須的data item property盡量在create時就帶入
有時會有null問題
後來發現問題在於data item的設定方法
var dataitem= Ti.UI.createTableCellView({
aa: '123'
});
dataitem.bb = '456';
在這寫法下,取得e.aa不會有問題
取得e.bb則會有10%成功機會
簡單來說就是把已知、必須的data item property盡量在create時就帶入
2012年6月4日 星期一
自訂scrollableview的pagecontrol 顏色
Tintaium scrollablevie有提供pageontrolColor屬性
不過這屬性設定的是pageControl的背景顏色
前景(dot)顏色不能自訂
查了一下,剛好有人針對這點做出一個自訂模組
原始版本
https://gist.github.com/2417902
加強:加入scrollableView.addEventListener("postlayout", onPostLayout);
https://gist.github.com/2729533
用法
if(sView && sView.views && sView.views.length > 0) {
require('PageControl');
var sViewPagingControl = new PagingControl(sView);
sView.add(sViewPagingControl);
window.add(sView);
}
不過這個模組有幾個缺點
var container = Titanium.UI.createView({
bottom:0, //置底
left: 0,
width: scrollableView.width,
height: 20
});
for (var i = 0; i < numberOfPages; i++) {
page = Titanium.UI.createView({
borderRadius: 4,
width: 8,
height: 8,
//讓pageControl保持在view中間
left: (scrollableView.width- (15*numberOfPages))/2+15 * i,
backgroundColor: pageColor,
opacity: 0.5
});
不過這屬性設定的是pageControl的背景顏色
前景(dot)顏色不能自訂
查了一下,剛好有人針對這點做出一個自訂模組
原始版本
https://gist.github.com/2417902
加強:加入scrollableView.addEventListener("postlayout", onPostLayout);
https://gist.github.com/2729533
用法
if(sView && sView.views && sView.views.length > 0) {
require('PageControl');
var sViewPagingControl = new PagingControl(sView);
sView.add(sViewPagingControl);
window.add(sView);
}
不過這個模組有幾個缺點
- pageControl的顏色其實無法自訂,要自己修改
- paeControl的位置會固定在左邊中間,這也要自己修改
var container = Titanium.UI.createView({
bottom:0, //置底
left: 0,
width: scrollableView.width,
height: 20
});
for (var i = 0; i < numberOfPages; i++) {
page = Titanium.UI.createView({
borderRadius: 4,
width: 8,
height: 8,
//讓pageControl保持在view中間
left: (scrollableView.width- (15*numberOfPages))/2+15 * i,
backgroundColor: pageColor,
opacity: 0.5
});
2012年6月3日 星期日
rate app in titanium
在titanium 裡面加入 rate app 功能的作法
來源 https://gist.github.com/1011043
/**
* The following snippet will ask the user to rate your app the second time they launch it.
* It lets the user rate it now, "Remind Me Later" or never rate the app.
*/
var win = Ti.UI.createWindow({ backgroundColor: '#fff' });
win.addEventListener('open', checkReminderToRate);
win.add(Ti.UI.createLabel({ text: 'This is a simple app that will remind you to rate it.' }));
win.open();
function checkReminderToRate() {
var now = new Date().getTime();
var remindToRate = Ti.App.Properties.getString('RemindToRate');
if (!remindToRate) {
Ti.App.Properties.setString('RemindToRate', now);
}
else if (remindToRate < now) {
var alertDialog = Titanium.UI.createAlertDialog({
title: 'Please rate this app!',
message: 'Would you take a moment to rate this app?',
buttonNames: ['OK', 'Remind Me Later', 'Never'],
cancel: 2
});
alertDialog.addEventListener('click', function(evt) {
switch (evt.index) {
case 0:
Ti.App.Properties.setString('RemindToRate', Number.MAX_VALUE);
// NOTE: replace this with your own iTunes link; also, this won't WON'T WORK IN THE SIMULATOR!
if (Ti.Android) {
Ti.Platform.openURL('URL TO YOUR APP IN THE GOOGLE MARKETPLACE');
}
else {
Ti.Platform.openURL('URL TO YOUR APP IN THE ITUNES STORE');
}
break;
case 1:
// "Remind Me Later"? Ok, we'll remind them tomorrow when they launch the app.
Ti.App.Properties.setString('RemindToRate', now + (1000 * 60 * 60 * 24));
break;
case 2:
Ti.App.Properties.setString('RemindToRate', Number.MAX_VALUE);
break;
}
});
alertDialog.show();
}
}
來源 https://gist.github.com/1011043
/**
* The following snippet will ask the user to rate your app the second time they launch it.
* It lets the user rate it now, "Remind Me Later" or never rate the app.
*/
var win = Ti.UI.createWindow({ backgroundColor: '#fff' });
win.addEventListener('open', checkReminderToRate);
win.add(Ti.UI.createLabel({ text: 'This is a simple app that will remind you to rate it.' }));
win.open();
function checkReminderToRate() {
var now = new Date().getTime();
var remindToRate = Ti.App.Properties.getString('RemindToRate');
if (!remindToRate) {
Ti.App.Properties.setString('RemindToRate', now);
}
else if (remindToRate < now) {
var alertDialog = Titanium.UI.createAlertDialog({
title: 'Please rate this app!',
message: 'Would you take a moment to rate this app?',
buttonNames: ['OK', 'Remind Me Later', 'Never'],
cancel: 2
});
alertDialog.addEventListener('click', function(evt) {
switch (evt.index) {
case 0:
Ti.App.Properties.setString('RemindToRate', Number.MAX_VALUE);
// NOTE: replace this with your own iTunes link; also, this won't WON'T WORK IN THE SIMULATOR!
if (Ti.Android) {
Ti.Platform.openURL('URL TO YOUR APP IN THE GOOGLE MARKETPLACE');
}
else {
Ti.Platform.openURL('URL TO YOUR APP IN THE ITUNES STORE');
}
break;
case 1:
// "Remind Me Later"? Ok, we'll remind them tomorrow when they launch the app.
Ti.App.Properties.setString('RemindToRate', now + (1000 * 60 * 60 * 24));
break;
case 2:
Ti.App.Properties.setString('RemindToRate', Number.MAX_VALUE);
break;
}
});
alertDialog.show();
}
}
2012年5月30日 星期三
titanium url cheme設定
SDK 2.0.1 GA2下
Titanium 會自動設定url scheme
預設是application id最後單字
例如 com.demo.theappname
url scheme就是theappname
不過有一各小例外
當使用 us.adison.TheAppName時
url scheme是Theappname(只有首字大寫)
如果還是有問題,打開builer下的檔案檢查看看
iPhone: builder/iphone/info.list
<key>CFBundleURLName</key>
<string>com.demo.theappname</string>
<key>CFBundleURLSchemes</key>
<array>
<string>看這邊</string>
android
builder/android/AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.demo.theappname 這邊" android:versionCode="1"
android:versionName="1">
使用url scheme的方式可以參考
http://developer.appcelerator.com/question/120393/custom-url-scheme---iphone--android
// Save initial launch command line arguments
Ti.App.launchURL = '';
Ti.App.pauseURL = '';
var cmd = Ti.App.getArguments();
if ( (getTypeOf(cmd) == 'object') && cmd.hasOwnProperty('url') ) {
Ti.App.launchURL = cmd.url;
Ti.API.info( 'Launched with url = ' + Ti.App.launchURL );
}
// Save launch URL at the time last paused
Ti.App.addEventListener( 'pause', function(e) {
Ti.App.pauseURL = Ti.App.launchURL;
});
// After app is fully resumed, recheck if launch arguments
// have changed and ignore duplicate schemes.
Ti.App.addEventListener( 'resumed', function(e) {
Ti.App.launchURL = '';
cmd = Ti.App.getArguments();
if ( (getTypeOf(cmd) == 'object') && cmd.hasOwnProperty('url') ) {
if ( cmd.url != Ti.App.pauseURL ) {
Ti.App.launchURL = cmd.url;
Ti.API.info( 'Resumed with url = ' + Ti.App.launchURL );
}
}
});
Titanium 會自動設定url scheme
預設是application id最後單字
例如 com.demo.theappname
url scheme就是theappname
不過有一各小例外
當使用 us.adison.TheAppName時
url scheme是Theappname(只有首字大寫)
如果還是有問題,打開builer下的檔案檢查看看
iPhone: builder/iphone/info.list
<key>CFBundleURLName</key>
<string>com.demo.theappname</string>
<key>CFBundleURLSchemes</key>
<array>
<string>看這邊</string>
android
builder/android/AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.demo.theappname 這邊" android:versionCode="1"
android:versionName="1">
使用url scheme的方式可以參考
http://developer.appcelerator.com/question/120393/custom-url-scheme---iphone--android
// Save initial launch command line arguments
Ti.App.launchURL = '';
Ti.App.pauseURL = '';
var cmd = Ti.App.getArguments();
if ( (getTypeOf(cmd) == 'object') && cmd.hasOwnProperty('url') ) {
Ti.App.launchURL = cmd.url;
Ti.API.info( 'Launched with url = ' + Ti.App.launchURL );
}
// Save launch URL at the time last paused
Ti.App.addEventListener( 'pause', function(e) {
Ti.App.pauseURL = Ti.App.launchURL;
});
// After app is fully resumed, recheck if launch arguments
// have changed and ignore duplicate schemes.
Ti.App.addEventListener( 'resumed', function(e) {
Ti.App.launchURL = '';
cmd = Ti.App.getArguments();
if ( (getTypeOf(cmd) == 'object') && cmd.hasOwnProperty('url') ) {
if ( cmd.url != Ti.App.pauseURL ) {
Ti.App.launchURL = cmd.url;
Ti.API.info( 'Resumed with url = ' + Ti.App.launchURL );
}
}
});
2012年5月27日 星期日
Titanium ios/android同專案開發心得
這篇算是一個階段性的總結
先說一下專案過程,這是一個LBS型態專案
其中使用了一些比較fancy的UI/UX
也使用到了一些分享功能(簡訊、email之類、fb)
一開始是從ios版本做起
之前有一個lite的iOS版本,也是用Titanium開發的
這次開發pro版本時
由於繼承了lite版本的不少程式碼(約一半)
基本上開發速度蠻快的
Titanium在某些方面是有它的優勢存在的
包括
可以使用JS語法處理:
無論是iOS或android,要搞懂他們的語法和架構多少都需要一些時間,甚至是不少時間
而Titan提供用JS語法進行開發的功能,這點對於許多了解JS語法的開發者而言,一定是一個利多
但是由於不是原生語法,如果專案中要用到一些比較底層的功能,就會很麻煩
如果是Titan沒有提供支援的功能,也會很麻煩
整合了一些常見/常用的元件和方法
Titan在網路傳輸這塊整合的不錯,此外還包括FB、資料庫的語法整合也很方便
不過這三個領域在andoird或ios上都有一些不錯的整合元件
真的要說的話,大概只有fb的整合算是比較獨特和省時間
一開始寫ios版本時
大部分的時間都花在調整UI/UX上面
好的UI/UX是一個app一定要有的元素
UI/UX也許不用很獨特、很絢麗
但至少要是一個讓使用者可以很快速了解、使用的介面設計
這部份加入前後的修改,和一些思考及功能上的調整,大約花費一個多月左右完成
這期間使用Titanium處理iOS時,有碰到一些問題,但沒有多少bug出現
比較特殊的大概是Titanium還不支援ios上的簡訊功能
所以有引用SMS模組,但是SMS模組在使用上有一些問題
由於之後設計變更,沒有繼續使用,所以現在不確定是因為SMS模組的問題
還是因為把SMS模組套用到scrollview中的按鈕上的問題
(這部份之後會提到,Titnaium中並非所有元件都能配合無誤,目前為止,很多元件放在scrollview中常會出現一些不可理解的行為,或稱為bug…
在決定使用同一套程式碼進行android開發時,才真正陷入bug地獄..
首先,我要說明一下,以下提到的情況未必都是titanium的問題
android的版本之多、硬體組成之複雜從來不是新聞
即使使用原生android程式碼,也很少有人能保證不會碰到問題
其中尤其以影音相關功能最為複雜
但是在Titanium上,影音相關的問題我這次碰到的情況並不多
最主要的大概只有使用相機拍攝照片並上傳時,會一次記錄兩張照片的功能而已..
喔,使用相片膠卷挑選照片上傳好像也會讓照片自我複製一次…
還是先從ios/andorid的基本元件設計開始談起好了..
iOS和andoird的基本畫面設計本身是不同的
最簡單的就是andorid沒有上方的navbar設計
這種設計當然是可以模擬出來的
但是對應的navigation group功能就不是簡單的模擬可以做到的了
這就是同一套程式碼要對應android和ios時要碰到的第一個問題
這問題會很煩,但不是無解
只是要多花費一些心力去處理畫面進出時的設計
不過由於有了本來的ti for ios程式碼,加入這設計時可能會讓程式看起來有一點雜亂
接下來我碰到的問題在於ios獨特的元件設計
例如toolbar, systembutton
android在這方面非常欠缺
最簡單的例子是刪除用的垃圾桶圖示
在titnaium中,可以使用iphone.systembutton.delete這樣的簡單語法提取iOS的垃圾桶圖示作為按鈕
(雖然只能放在toolbar或navbar上)
但是在android(2.2)中並沒有(Titanium官方只宣告支援2.2,其他的版本多少有相容性,但是個人建議別去踩那地雷..你之後還有很多地雷可以踩個夠..)
在android上少了這設計就表示你需要自己弄一個按鈕,自己標明"刪除鈕"
如果想要精美的垃圾桶圖示,請找美設人員討論..
平心而論,這不是大問題
就算是在iOS上,由於toolbar的限制,這種系統icon也不是隨時都可以使用的
而且這是ios/android 在基本架構上的不同,與titanium本身優劣並無干係
當一套app要在這兩個不同平台上開發時,這本來就是必須花的功夫之一
不過加入前面說的ti for ios程式碼後,會讓整個程式碼結構看起來更雜亂了一點
不過這部份和程式流程/UI結構關係並不大,其實還可以接受
修改起來也不是太麻煩
處理這部份問題時,我主要的工作都在於搜尋ios元件,然後替換成對應的android可使用元件
修改這部份後,原始專案終於可以在android平台上測試了
這時候android解析度不統一的問題就出來了
ios上由於有自動判斷解析度加入@2x而且長寬比不變的設計,在iphone 3gs/4/4s上只需要注意某些硬體元件是否存在就可以(雖然這三種機型的硬體元件只有規格差別而沒有是否存在的差異)
但是android上面的螢幕長寬比、解析度差異很大,在這部份就要特別小心
這部份我們所採用的是懶人作法:強制使用預設長寬比設計
主要是在tiapp.xml中加入一個簡單的設定
接下來才是正式的測試
首先碰到的是android平台在GPS定位上的速度比ios慢,慢很多..
所以需要修改原本的單線流程,改成使用callback方式,讓機器抓到GPS訊號後才執行對應程式碼
這部份ios可以通用(說實話這是比較好的作法)
但是接下來就是一堆地獄了..
說真的,現在想起來,我覺得titanium對於ios的支援程度好很多..
我並不真的確定原因..但是我覺得和ios的穩定性以及架構相對完整有很大關係
我們的專案由於有特地強調UI/UX,並加入一些作法減少使用者的等待時間
所以在物件架構上相對比較複雜,有2~4個物件常駐背景並等候呼叫和執行
這些物件在iOS上使用時,透過navigation group的push/pop方法就可以運用
但是在android上不行..在android上使用back或close時,物件就會被關閉
這問題的出現,一方面是因為我方原始的設計不夠成熟
但也不能忽略titanium在這方面的移植性設計不夠完善才導致這種令人騎虎難下的情況出現
由於時間壓力,這方面我們使用了簡單的show/hide方法繞過
使用這方法繞過的一個主要考量在於這些設計和程式行為有關
所以不再能像UI元件一樣使用簡單的if(iiOS them ooxx 方式來進行簡單的分支處理
可是這還沒結束…
titanium on android上,對於層層套疊的元件在編譯時很容易出問題
一個簡單的 xxx.hide指令
當xxx"直接"附屬於最底層的window時,是很正常的
但是當xxx放置在scollview,scrollview又放置在tablerow中時,hide指令就無效了..
在iOS上一開始也曾經出現類似問題,但是當時出現的問題主要在於效能方面(tableview先出現,一閃之後才會出現裡面的元件)
元件的基礎指令如hide 無效的問題並未被觀察到
另外,如同上上一段所說的,為了減少使用者等待時間,我們有一些物件是常駐背景處理的
因此無可避免的,我們有一些事件處理會呼叫這些背景物件執行,也會根據執行結果安排元件並顯示出來
但是在操作這些背景元件時,titanium對這些元件的處理方式有奇妙的不同
在iOS上,開啟一個window放置背景後,可以輕易的操控其中的元件屬性
並在操作完成後顯示window
但是在android上,這些元件未必是可操控的,這問題尤其容易發生在元件不直接附屬於window時
即使是在同一個active window中的元件,由於上一段所提及的因素,要操作其行為也未必可行
當元件是scroll開頭的scrollview或scrollableview時尤其明顯
另一個問題是,在android上,當在table row中加入一個圖片當按鈕
指定圖片點擊動作為開啟新的window,當window關閉時
android有可能出現z-order錯誤問題
這問題幾近無解
因為他牽涉到的是titanium編譯指令的方法和android的行為
唯一可信的解法是使用heavyweight方式開啟window,如 modal:true
不過這解法也並非100%完美..
整體而言,將這套在ios上完美的程式碼轉移到android平台時
只有和UI無關的傳值行為可以不用花心思處理
其他的諸如表格點擊之類動作都或多或少有一些相容性問題(ios上e.rowData可以用,android上可能就要測試e.source之類)
結論
如果將titanium定位在快速建立簡單的iphone app的話,titanium還蠻完美的
如果想用titanium開發簡單的android app,應該也不會碰到太大問題
但是想要用同一套程式碼同時覆蓋兩個平台的話,我會建議先行判斷你的app是否符合以下條件
畫面設計簡單:這方面說的不是功能上的簡單,而是UI架構上的簡單,建議最多不要超過二層
也就是頂多用到 base window/wrapper/ UI 這樣的設計就好
這條件並不表示你的畫面要維持素淨,只要在一層之內,你想加多少image其實都不是問題
如果可能的話,最好是只有一層如 window/lavel
程式架構簡單:盡量維持一次只有一個window,背景最好不要有其他元件
這條件可能會讓app在開啟新的畫面時多花費一些時間,但是可以有效的降低你處理背景物件時花費的時間。一些額外的好處則是可以節省app的記憶體空間
UX設計不要太複雜:一些動畫還是可以用的,但是別讓這些動畫擴及到active window以外的元件
盡量遵守MVC設計:程式歸程式,ui歸UI,資料歸資料,千萬別讓資料和ui卡在一起。
盡量使用callback:如果你不確定怎麼把app架構拆成MVC,起碼你可以使用callback方式來處理程式。當然兩者一起就更好了,這可以讓你的程式更好掌控和管理
最後一個問題,我會後悔學習Titanium或用它開發嗎?
我的回答是不會,Titanium在建立app上確實有它的優勢和特色,包括快速的學習曲線和快速的開發
但是它的應用範圍顯然沒有原生語言/IDE來的廣泛和深入(喔,Titanium沒有 xcode的interface builder之類拉畫面的附屬程式,不過反正android也沒有這種支援程式..應該沒有吧)
當然你可以自己建立Titanium module來擴展它的能力,不過走到那一步的話,你還能享受到多少快速/簡易特性?
titanium在原生UI元件的支援上未必100%支援(例如ios上的sms功能...)
不過一些簡單的元件如label, button之類,基本上都有支援
但是當ios上完美運作的程式卻在android上由於UI套疊後的存取/控制問題變成蟲族母巢後
我就開始後悔用它做這種開發了
記得,別給Titanium太大的發揮空間,能簡單就盡量簡單
補充幾點
Titanium的debug能力非常基本,除了簡單的語法錯誤和log方法之外,幾乎沒有其他debug作法
不過可以透過使用xcode/eclipse開啟編譯過專案的方式處理
和ios/android相比,Titanium api和開發資訊相對而言少很多
最後
Titanium用在iOS上比android穩定很多,如果只是用來顯示網頁資料的app,更是幾乎不會有任何問題
先說一下專案過程,這是一個LBS型態專案
其中使用了一些比較fancy的UI/UX
也使用到了一些分享功能(簡訊、email之類、fb)
一開始是從ios版本做起
之前有一個lite的iOS版本,也是用Titanium開發的
這次開發pro版本時
由於繼承了lite版本的不少程式碼(約一半)
基本上開發速度蠻快的
Titanium在某些方面是有它的優勢存在的
包括
可以使用JS語法處理:
無論是iOS或android,要搞懂他們的語法和架構多少都需要一些時間,甚至是不少時間
而Titan提供用JS語法進行開發的功能,這點對於許多了解JS語法的開發者而言,一定是一個利多
但是由於不是原生語法,如果專案中要用到一些比較底層的功能,就會很麻煩
如果是Titan沒有提供支援的功能,也會很麻煩
整合了一些常見/常用的元件和方法
Titan在網路傳輸這塊整合的不錯,此外還包括FB、資料庫的語法整合也很方便
不過這三個領域在andoird或ios上都有一些不錯的整合元件
真的要說的話,大概只有fb的整合算是比較獨特和省時間
一開始寫ios版本時
大部分的時間都花在調整UI/UX上面
好的UI/UX是一個app一定要有的元素
UI/UX也許不用很獨特、很絢麗
但至少要是一個讓使用者可以很快速了解、使用的介面設計
這部份加入前後的修改,和一些思考及功能上的調整,大約花費一個多月左右完成
這期間使用Titanium處理iOS時,有碰到一些問題,但沒有多少bug出現
比較特殊的大概是Titanium還不支援ios上的簡訊功能
所以有引用SMS模組,但是SMS模組在使用上有一些問題
由於之後設計變更,沒有繼續使用,所以現在不確定是因為SMS模組的問題
還是因為把SMS模組套用到scrollview中的按鈕上的問題
(這部份之後會提到,Titnaium中並非所有元件都能配合無誤,目前為止,很多元件放在scrollview中常會出現一些不可理解的行為,或稱為bug…
在決定使用同一套程式碼進行android開發時,才真正陷入bug地獄..
首先,我要說明一下,以下提到的情況未必都是titanium的問題
android的版本之多、硬體組成之複雜從來不是新聞
即使使用原生android程式碼,也很少有人能保證不會碰到問題
其中尤其以影音相關功能最為複雜
但是在Titanium上,影音相關的問題我這次碰到的情況並不多
最主要的大概只有使用相機拍攝照片並上傳時,會一次記錄兩張照片的功能而已..
喔,使用相片膠卷挑選照片上傳好像也會讓照片自我複製一次…
還是先從ios/andorid的基本元件設計開始談起好了..
iOS和andoird的基本畫面設計本身是不同的
最簡單的就是andorid沒有上方的navbar設計
這種設計當然是可以模擬出來的
但是對應的navigation group功能就不是簡單的模擬可以做到的了
這就是同一套程式碼要對應android和ios時要碰到的第一個問題
這問題會很煩,但不是無解
只是要多花費一些心力去處理畫面進出時的設計
不過由於有了本來的ti for ios程式碼,加入這設計時可能會讓程式看起來有一點雜亂
接下來我碰到的問題在於ios獨特的元件設計
例如toolbar, systembutton
android在這方面非常欠缺
最簡單的例子是刪除用的垃圾桶圖示
在titnaium中,可以使用iphone.systembutton.delete這樣的簡單語法提取iOS的垃圾桶圖示作為按鈕
(雖然只能放在toolbar或navbar上)
但是在android(2.2)中並沒有(Titanium官方只宣告支援2.2,其他的版本多少有相容性,但是個人建議別去踩那地雷..你之後還有很多地雷可以踩個夠..)
在android上少了這設計就表示你需要自己弄一個按鈕,自己標明"刪除鈕"
如果想要精美的垃圾桶圖示,請找美設人員討論..
平心而論,這不是大問題
就算是在iOS上,由於toolbar的限制,這種系統icon也不是隨時都可以使用的
而且這是ios/android 在基本架構上的不同,與titanium本身優劣並無干係
當一套app要在這兩個不同平台上開發時,這本來就是必須花的功夫之一
不過加入前面說的ti for ios程式碼後,會讓整個程式碼結構看起來更雜亂了一點
不過這部份和程式流程/UI結構關係並不大,其實還可以接受
修改起來也不是太麻煩
處理這部份問題時,我主要的工作都在於搜尋ios元件,然後替換成對應的android可使用元件
修改這部份後,原始專案終於可以在android平台上測試了
這時候android解析度不統一的問題就出來了
ios上由於有自動判斷解析度加入@2x而且長寬比不變的設計,在iphone 3gs/4/4s上只需要注意某些硬體元件是否存在就可以(雖然這三種機型的硬體元件只有規格差別而沒有是否存在的差異)
但是android上面的螢幕長寬比、解析度差異很大,在這部份就要特別小心
這部份我們所採用的是懶人作法:強制使用預設長寬比設計
主要是在tiapp.xml中加入一個簡單的設定
接下來才是正式的測試
首先碰到的是android平台在GPS定位上的速度比ios慢,慢很多..
所以需要修改原本的單線流程,改成使用callback方式,讓機器抓到GPS訊號後才執行對應程式碼
這部份ios可以通用(說實話這是比較好的作法)
但是接下來就是一堆地獄了..
說真的,現在想起來,我覺得titanium對於ios的支援程度好很多..
我並不真的確定原因..但是我覺得和ios的穩定性以及架構相對完整有很大關係
我們的專案由於有特地強調UI/UX,並加入一些作法減少使用者的等待時間
所以在物件架構上相對比較複雜,有2~4個物件常駐背景並等候呼叫和執行
這些物件在iOS上使用時,透過navigation group的push/pop方法就可以運用
但是在android上不行..在android上使用back或close時,物件就會被關閉
這問題的出現,一方面是因為我方原始的設計不夠成熟
但也不能忽略titanium在這方面的移植性設計不夠完善才導致這種令人騎虎難下的情況出現
由於時間壓力,這方面我們使用了簡單的show/hide方法繞過
使用這方法繞過的一個主要考量在於這些設計和程式行為有關
所以不再能像UI元件一樣使用簡單的if(iiOS them ooxx 方式來進行簡單的分支處理
可是這還沒結束…
titanium on android上,對於層層套疊的元件在編譯時很容易出問題
一個簡單的 xxx.hide指令
當xxx"直接"附屬於最底層的window時,是很正常的
但是當xxx放置在scollview,scrollview又放置在tablerow中時,hide指令就無效了..
在iOS上一開始也曾經出現類似問題,但是當時出現的問題主要在於效能方面(tableview先出現,一閃之後才會出現裡面的元件)
元件的基礎指令如hide 無效的問題並未被觀察到
另外,如同上上一段所說的,為了減少使用者等待時間,我們有一些物件是常駐背景處理的
因此無可避免的,我們有一些事件處理會呼叫這些背景物件執行,也會根據執行結果安排元件並顯示出來
但是在操作這些背景元件時,titanium對這些元件的處理方式有奇妙的不同
在iOS上,開啟一個window放置背景後,可以輕易的操控其中的元件屬性
並在操作完成後顯示window
但是在android上,這些元件未必是可操控的,這問題尤其容易發生在元件不直接附屬於window時
即使是在同一個active window中的元件,由於上一段所提及的因素,要操作其行為也未必可行
當元件是scroll開頭的scrollview或scrollableview時尤其明顯
另一個問題是,在android上,當在table row中加入一個圖片當按鈕
指定圖片點擊動作為開啟新的window,當window關閉時
android有可能出現z-order錯誤問題
這問題幾近無解
因為他牽涉到的是titanium編譯指令的方法和android的行為
唯一可信的解法是使用heavyweight方式開啟window,如 modal:true
不過這解法也並非100%完美..
整體而言,將這套在ios上完美的程式碼轉移到android平台時
只有和UI無關的傳值行為可以不用花心思處理
其他的諸如表格點擊之類動作都或多或少有一些相容性問題(ios上e.rowData可以用,android上可能就要測試e.source之類)
結論
如果將titanium定位在快速建立簡單的iphone app的話,titanium還蠻完美的
如果想用titanium開發簡單的android app,應該也不會碰到太大問題
但是想要用同一套程式碼同時覆蓋兩個平台的話,我會建議先行判斷你的app是否符合以下條件
畫面設計簡單:這方面說的不是功能上的簡單,而是UI架構上的簡單,建議最多不要超過二層
也就是頂多用到 base window/wrapper/ UI 這樣的設計就好
這條件並不表示你的畫面要維持素淨,只要在一層之內,你想加多少image其實都不是問題
如果可能的話,最好是只有一層如 window/lavel
程式架構簡單:盡量維持一次只有一個window,背景最好不要有其他元件
這條件可能會讓app在開啟新的畫面時多花費一些時間,但是可以有效的降低你處理背景物件時花費的時間。一些額外的好處則是可以節省app的記憶體空間
UX設計不要太複雜:一些動畫還是可以用的,但是別讓這些動畫擴及到active window以外的元件
盡量遵守MVC設計:程式歸程式,ui歸UI,資料歸資料,千萬別讓資料和ui卡在一起。
盡量使用callback:如果你不確定怎麼把app架構拆成MVC,起碼你可以使用callback方式來處理程式。當然兩者一起就更好了,這可以讓你的程式更好掌控和管理
最後一個問題,我會後悔學習Titanium或用它開發嗎?
我的回答是不會,Titanium在建立app上確實有它的優勢和特色,包括快速的學習曲線和快速的開發
但是它的應用範圍顯然沒有原生語言/IDE來的廣泛和深入(喔,Titanium沒有 xcode的interface builder之類拉畫面的附屬程式,不過反正android也沒有這種支援程式..應該沒有吧)
當然你可以自己建立Titanium module來擴展它的能力,不過走到那一步的話,你還能享受到多少快速/簡易特性?
titanium在原生UI元件的支援上未必100%支援(例如ios上的sms功能...)
不過一些簡單的元件如label, button之類,基本上都有支援
但是當ios上完美運作的程式卻在android上由於UI套疊後的存取/控制問題變成蟲族母巢後
我就開始後悔用它做這種開發了
記得,別給Titanium太大的發揮空間,能簡單就盡量簡單
補充幾點
Titanium的debug能力非常基本,除了簡單的語法錯誤和log方法之外,幾乎沒有其他debug作法
不過可以透過使用xcode/eclipse開啟編譯過專案的方式處理
和ios/android相比,Titanium api和開發資訊相對而言少很多
最後
Titanium用在iOS上比android穩定很多,如果只是用來顯示網頁資料的app,更是幾乎不會有任何問題
2012年5月25日 星期五
titanium android 下 ambiguous z order 問題
這篇文章給後來有碰到這問題的人當參考吧
SDK 2.0.1GA2
簡單結論:Titanium on android中,開啟new window時,
如果是tablerow , click事件請使用row內的button 別用其他元件(包括row.click事件
或者是使用 modal: ture方法開啟
把app轉換到android時
Titanium一直出現 ambiguous-z-order 問題
根據http://engineering.rentgeek.com/titanium-ambiguous-z-order-android 的說法
使用row中的button 事件開啟新視窗時,就不會有這問題
而使用 row click事件就會有
他推測這是因為點擊tab group.tap1.table.row 時
開啟新window後,按下close按鈕時執行倒退動作時
系統會嘗試去取得原本focus的元件(row)
但是由於這元件在window.table.row中,APP定位不出來,就造成了z order問題
他用了image 元件當說明,可是image和他推論的button應該是同一級別元件..
結果他也不知道為什麼image會有這問題 orz
他的解法是加入modal true設定來避開
可是這解法對我而言不適用..
追加
http://ti.masuidrive.jp/topic.php?id=333
這篇是使用table + scrollview/scrollable view
也是有z-index問題
SDK 2.0.1GA2
簡單結論:Titanium on android中,開啟new window時,
如果是tablerow , click事件請使用row內的button 別用其他元件(包括row.click事件
或者是使用 modal: ture方法開啟
把app轉換到android時
Titanium一直出現 ambiguous-z-order 問題
根據http://engineering.rentgeek.com/titanium-ambiguous-z-order-android 的說法
使用row中的button 事件開啟新視窗時,就不會有這問題
而使用 row click事件就會有
他推測這是因為點擊tab group.tap1.table.row 時
開啟新window後,按下close按鈕時執行倒退動作時
系統會嘗試去取得原本focus的元件(row)
但是由於這元件在window.table.row中,APP定位不出來,就造成了z order問題
他用了image 元件當說明,可是image和他推論的button應該是同一級別元件..
結果他也不知道為什麼image會有這問題 orz
他的解法是加入modal true設定來避開
可是這解法對我而言不適用..
追加
http://ti.masuidrive.jp/topic.php?id=333
這篇是使用table + scrollview/scrollable view
也是有z-index問題
2012年5月23日 星期三
Titanium 雙行動平台 textarea行為差異
keyboard:
android沒有toolbar這設定,我也不確定是否有辦法在keyboard上另外添加view
這會牽涉到done/cancel這兩個必須按鈕的配置
如果可以的話,盡量使用modal window處理
如果是單行,可以用enter判斷
使用 Titanium 開發 android和iphone app心得
隨著andoir的改版進度
我對titanium dev on android越來越灰心
這裡面當然多少牽涉到原本的程式架構有點複雜的因素
不過多半的問題在於iphone與android的基本差別
另一個問題是Titanium只確定支援android 2.2
這裡面會牽涉到一些問題
android 4.0或更高版本是否支援Ti創建的APP?
在Ti中,怎麼用一套程式碼走遍android SDK 2.x -4.x甚至更高?
如果不行,這之間的支援怎麼解決?
如果你也要使用titanium進行開發
請盡量確保你的程式使用的元件夠基本、流程不要太複雜
盡量一次只使用一個畫面,使用適當的global var儲存資料
window open時才建立對應畫面展現(我這次有一半因素栽在這邊)
如果考慮使用相同layout, 在建立window時,就要考慮上方的navbar要怎麼在android中展現
//我想過建立一個custom winnow覆蓋title元件,不過下次再說吧
資料傳輸只牽涉到OSI前三層
不過以上條件如果全都達成
那做出來的app大概也沒啥特殊看頭,大概只會是專案app而不會是產品 XD
所以最好的作法可能會是在Ti中使用很嚴格的MVC架構,這樣才可能確保完整的移植性
可是能做到這點的人中,其中大部分的人轉學android或iphone可能也不會多花太多時間(有興趣的話..
如果讓我說,Titanium的用法應該是用來快速創建單一平台app
如果考慮要覆蓋多重平台,至少要把資料操作部分程式完全抽離
這樣就可以讓多重平台app使用同一套資料操作app,但使用各自的ui/controller方法
如果堅持要用同一專案,那至少可以使用不同的UI/control方法
放在同一個js中,判斷if android, 然後計算width/height並不會讓日子好過多少
Titanium在資料操作部分的程式轉換做得不錯,也整合的不錯
然後在前端ui部分,也許可以說是因為ios和android本身就有很大差距
但是用起來就是非常的不順暢!
當很順暢(隨便)的建立了單一平台app,然後想轉換到另一平台時
這UI的不同與相應產生的工作壓力所帶來的挫折感在這時最為明顯(例如此時的我 orz
2012年5月22日 星期二
Titanium SDK 2.0.1GA android下talbeviewrow高度
雖然從sdk2開始,height/width : 'auto'作法被官方捨棄
不過在2.0.1Ga下,android環境中tableviewrow使用height : Ti.UI.SIZE是有問題的(iphone則OK
所以還是要用height : 'auto'寫法
等sdk改版後,這問題可能也許大概就會被修掉?
2012/5/26 上午11:18
sdk 2.0.1ga2
andr下,width要使用 'auto',不支援Ti.UI.SIZE
不過在2.0.1Ga下,android環境中tableviewrow使用height : Ti.UI.SIZE是有問題的(iphone則OK
所以還是要用height : 'auto'寫法
等sdk改版後,這問題可能也許大概就會被修掉?
2012/5/26 上午11:18
sdk 2.0.1ga2
andr下,width要使用 'auto',不支援Ti.UI.SIZE
android modal window無法出現兩次
根據
http://developer.appcelerator.com/question/123838/android-modal-window-wont-open-twice#215617
在android中,win1.open({modal: true})後
按下back鍵時,win1會被destroy
當win1是在事件程式碼外建立時,就會出錯
理論上應該有解決方法:win1中覆蓋android:back事件隱藏win1
不過由於使用modal方式開啟的window是heavyweight window, 不支援hide方法只支援close方法
而close方法也會destroy window reference… 等於是同一條路 orz
然後其他的方式如zIndex方法也無效..
簡單來說,就是使用modal方式開啟的window無法用close以外方式隱藏、關閉
雖然modal window可以支援android:back按鈕
不過使用modal window作為navigation group的替代方案是有問題的
還是乖乖使用tabgroup方式比較好
http://developer.appcelerator.com/question/123838/android-modal-window-wont-open-twice#215617
在android中,win1.open({modal: true})後
按下back鍵時,win1會被destroy
當win1是在事件程式碼外建立時,就會出錯
理論上應該有解決方法:win1中覆蓋android:back事件隱藏win1
不過由於使用modal方式開啟的window是heavyweight window, 不支援hide方法只支援close方法
而close方法也會destroy window reference… 等於是同一條路 orz
然後其他的方式如zIndex方法也無效..
簡單來說,就是使用modal方式開啟的window無法用close以外方式隱藏、關閉
雖然modal window可以支援android:back按鈕
不過使用modal window作為navigation group的替代方案是有問題的
還是乖乖使用tabgroup方式比較好
2012年5月21日 星期一
titanium, tableview rowdata.click找不到e.rowData.xxxx資料
在titanium中
tableview下,同一段click事件中iPhone找得到row data.xxx資料,可是android不行..
tableview.addEventListener('click', function(e) {
if(!e.rowData.xxxx) {
alert('no ios markerid');
return;
}
這個問題非常古怪,古怪到我差點和夥伴翻臉討論是否要放棄titanium框架
不過解法異常簡單..
主要是塞row.xxxx的時機
使用以下方式設定資料即可
var row=Ti.ui.createtableviewrow({
xxx: 123,
yyy : 456
});
千萬別用
var row = Ti.ui.ceatetableviewrow({
});
row.xxx=123;
row.yyy=456;
這種用法在iphone正常
但是android(至少是google pai 2.2)下會有隨機性的資料遺失問題發生
2012/5/26 上午11:13更新
以上使用方法是正確的
不過當row是放在section中時
section1.add(row)
在android中,table.click事件
使用e.rowData會抓不到資料
目前確定這種情況下使用 e.row.xxx可以抓到資料
e.row在其他地方的適用性尚未測試
tableview下,同一段click事件中iPhone找得到row data.xxx資料,可是android不行..
tableview.addEventListener('click', function(e) {
if(!e.rowData.xxxx) {
alert('no ios markerid');
return;
}
這個問題非常古怪,古怪到我差點和夥伴翻臉討論是否要放棄titanium框架
不過解法異常簡單..
主要是塞row.xxxx的時機
使用以下方式設定資料即可
var row=Ti.ui.createtableviewrow({
xxx: 123,
yyy : 456
});
千萬別用
var row = Ti.ui.ceatetableviewrow({
});
row.xxx=123;
row.yyy=456;
這種用法在iphone正常
但是android(至少是google pai 2.2)下會有隨機性的資料遺失問題發生
2012/5/26 上午11:13更新
以上使用方法是正確的
不過當row是放在section中時
section1.add(row)
在android中,table.click事件
使用e.rowData會抓不到資料
目前確定這種情況下使用 e.row.xxx可以抓到資料
e.row在其他地方的適用性尚未測試
2012年5月20日 星期日
Titanium map annoyation點擊事件: android無法觸發
Titanium map annoyation點擊事件: android無法觸發
簡單來說,annotation點擊在
http://developer.appcelerator.com/question/117350/annotation-click-events-not-working-on-android
http://www.pastie.org/1756264
mapview.addEventListener('click', function(e) {
if(e.clicksource == "title" || e.clicksource == "subtitle") {
var win1 = Titanium.UI.createWindow({
url:"club.js",
club_id:e.annotation.myid,
title:e.annotation.title
});
Titanium.UI.currentTab.open(win1,{animated:true});
}
});
//補充
http://developer.appcelerator.com/question/116634/map-annotation-not-showing-right-left-buttonview
簡單來說,annotation點擊在
http://developer.appcelerator.com/question/117350/annotation-click-events-not-working-on-android
http://www.pastie.org/1756264
mapview.addEventListener('click', function(e) {
if(e.clicksource == "title" || e.clicksource == "subtitle") {
var win1 = Titanium.UI.createWindow({
url:"club.js",
club_id:e.annotation.myid,
title:e.annotation.title
});
Titanium.UI.currentTab.open(win1,{animated:true});
}
});
//補充
http://developer.appcelerator.com/question/116634/map-annotation-not-showing-right-left-buttonview
2012年4月20日 星期五
Titanium SDK 2, studio 2釋出
號稱四月要放出的SDK 2終於出來了
對我而言最主要的優點是支援了Xcode4.3
終於可以使用xcode4.3了(因為偶爾有在開發其他程式..
此外,studio 2也可以用了
studio 2比studio 1好很多
反應比較迅速
支援自定的方法
雖然android模擬器的Ti.API.info方法不知道為何出現了問題..(不確定studio 1有沒有支援就是了
另外有一個小問題是我習慣使用暗系主題
但是studio 2在compile時,會自動對某些行列進行選取動作造成反白
這點蠻討厭的
除此之外,整體感覺良好
對我而言最主要的優點是支援了Xcode4.3
終於可以使用xcode4.3了(因為偶爾有在開發其他程式..
此外,studio 2也可以用了
studio 2比studio 1好很多
反應比較迅速
支援自定的方法
雖然android模擬器的Ti.API.info方法不知道為何出現了問題..(不確定studio 1有沒有支援就是了
另外有一個小問題是我習慣使用暗系主題
但是studio 2在compile時,會自動對某些行列進行選取動作造成反白
這點蠻討厭的
除此之外,整體感覺良好
2012年4月12日 星期四
Titanium iOS/android共同專案注意要點
android測試方法
成功安裝app後,出現錯誤選擇continue, 然後修改
修改完畢在模擬器重新執行app就可以了
錯誤會在android的runtime環境出現錯誤視窗,console無效..
目前測試 info是否有效中
titanium在MAC上的anroid模擬器不太穩
同一個專案設定,跑google api 2.2, 顯示螢幕從HVGA換成WVGA854就不能執行
我已經放棄使用模擬器,直接跑實機了
而且模擬器也不支援Ti.API.info/debug…
最後,這樣做還有一個好處,修改完畢後可以直接測試ios版本與android版本
titanium studio記錄iOS debug資訊
eclipse記錄android debug資訊
成功安裝app後,出現錯誤選擇continue, 然後修改
修改完畢在模擬器重新執行app就可以了
錯誤會在android的runtime環境出現錯誤視窗,console無效..
目前測試 info是否有效中
- iOS有toolbar, android沒有,要用view代替
- 動畫功能只有ios有
- 見鬼的navigationgroup替代問題..
- android的GPS警告視窗不能關閉?
- iOS的Navagationgroup完全不能用,還好可以把navgrp的底層直接開起來執行。
- toolbar按鈕非常麻煩,這大概會是最花力氣的部份(把所有地雷踩光之後..
- android的GPS要開eclipse使用DDMS控制傳送座標
- android的GPS回應較慢,"一定要使用"callback方式或app.event方式處理gps事件
- mapview: android中每個應用程式中只能有一個mapview,這個問題很大、非常大
- 表格click事件:要使用e.source不能用e.rowData(SDK差異?還是平台差異?最有趣的是,iphone/android上的方法不同,在不同專案中也不同 orzT專案:android要用e.source, iOS要用e.rowDatac專案:and/ios都可以用e.source方法傳遞參數
- scrollable view的render方法不同:之前在scrabble view上使用的tp[=100方式插入view並保留上方title方式,在android中scrabble view不會露出背景,必須修改scrabble view才行(不過修改完結果還沒在iPhone上測試
- iOS.toolbar = android.menu: iOS的toolbar在android上的實作有點麻煩(本來想做在上方的title,學play作法,看來google也覺得iOS的作法不錯?)不過那設定有點麻煩..win.title還無法使用,所以比較直觀(偷懶)的作法是把ios.toolbar內容做成android.menu內容(而且還不用煩惱少了flex space後的位置問題 XD
- android和iOS的視窗起始有點不太一樣androi中,每個畫面都是一個window,使用一個全視窗view的情況並不多而iOS中,很多視覺效果都是靠view之間的切換而達成在設定並行版本時,這一點需要多加考慮
- 2012/4/23 最後還是卡在toolbar這一塊了 XDiOS中,很多情況下會把按鈕放在tile/navigation bar上不過android似乎沒有這樣的設計,主要是靠menu雖然最近有很多 android app也有tile bar設計,不過那個似乎是靠程式設計達成而非原生元件,簡單來說,就是要另外添加才行,因為位置是在最上面,一開始設計時沒有考慮到這點就會影響到所有物件位置。
titanium在MAC上的anroid模擬器不太穩
同一個專案設定,跑google api 2.2, 顯示螢幕從HVGA換成WVGA854就不能執行
我已經放棄使用模擬器,直接跑實機了
而且模擬器也不支援Ti.API.info/debug…
最後,這樣做還有一個好處,修改完畢後可以直接測試ios版本與android版本
titanium studio記錄iOS debug資訊
eclipse記錄android debug資訊
2012年4月10日 星期二
mac上建立android虛擬環境問題
延續上一篇的建立android..
可以參考這篇 http://justfly.idv.tw/2012/02/08/Just_1067.html
可以參考這篇 http://justfly.idv.tw/2012/02/08/Just_1067.html
- 要把iPhone圖檔copy到android資料夾,不然compile不會過
- i18n檔名有所不同,iOS可以用的zh-Hant在android中似乎不接受?
- android的編譯檔案對於i18n檔案的檢查比iOS嚴格.. 在ios中沒有檢查出來的重複定義字串在andorid編譯時造成了錯誤
- Ti.API.info無效…必須要使用eclipse開啟DDMS查看log和info資訊。這點有些奇特,目前回報的人不多,不確定原因何在?
2012年4月9日 星期一
titanium iphone專案加入Android之環境設定
我一開始設定titanium專案時,直接把android排除
不過今天開始要測試android環境
然後就發現android不能勾選(這就叫自作孽? XDD
檢查了一下,發現有幾個地方需要調整
最基本的android SDK就不說了
在Titanium專案部分,有一些地方需要加入
resource下面需要加入android對應的資料夾

Tiapp.xml中,需要加入運行環境

同樣Tiapp.xml,加入SDK宣告
不過今天開始要測試android環境
然後就發現android不能勾選(這就叫自作孽? XDD
檢查了一下,發現有幾個地方需要調整
最基本的android SDK就不說了
在Titanium專案部分,有一些地方需要加入
resource下面需要加入android對應的資料夾
Tiapp.xml中,需要加入運行環境
同樣Tiapp.xml,加入SDK宣告
2012年3月30日 星期五
多國語言處理..又一個地雷
2012/3/30 下午8:24
Ti SDK: 1.8.2
Titanium的多國語言字串中不能放入特殊符號,例如<br />
例如 <string name="poidetail_share_title">分享給朋友<br />我要換行</string>
這樣的字串只會parse出"分享給朋友"字串
嘗試過\/都沒用
所以用自定的換行符號取代
沒想到又碰到第二個雷 XD
var str= L('poidetail_share_title');
str.replace('br', '<br />');
上面的指令是無效的
查了一下,有人提出類似問題
原因似乎是str不會被判斷為字串(Titanium SDK好像連JS的缺點都implement了...)
解決方法是把str toString()後再處理
阿阿阿阿阿阿阿
我討厭這種不指定型別的作法 orz
附帶說明
Titanium的string.format吃的是%s, 進階作法是$1%s, $2%s
Ti SDK: 1.8.2
Titanium的多國語言字串中不能放入特殊符號,例如<br />
例如 <string name="poidetail_share_title">分享給朋友<br />我要換行</string>
這樣的字串只會parse出"分享給朋友"字串
嘗試過\/都沒用
所以用自定的換行符號取代
沒想到又碰到第二個雷 XD
var str= L('poidetail_share_title');
str.replace('br', '<br />');
上面的指令是無效的
查了一下,有人提出類似問題
原因似乎是str不會被判斷為字串(Titanium SDK好像連JS的缺點都implement了...)
解決方法是把str toString()後再處理
阿阿阿阿阿阿阿
我討厭這種不指定型別的作法 orz
附帶說明
Titanium的string.format吃的是%s, 進階作法是$1%s, $2%s
titanium systembutton適用環境
根據http://developer.appcelerator.com/apidoc/mobile/latest/Titanium.UI.Button-object
system button只能用在以下環境
Titanium.UI.iOS.Toolbar. The items array can contain system buttons.
Titanium.UI.iPad.Popover. The leftNavButton and rightNavButton properties can refer to system buttons
Titanium.UI.iPad.SplitWindow. The toolbar array can contain system buttons.
以下環境需要用toolbar放置
Titanium.UI.TextField. The keyboardToolbar array can contain system buttons.
Titanium.UI.TextArea. The keyboardToolbar array can contain system buttons.
Titanium.UI.Window. The leftNavButton and rightNavButton properties can refer to system buttons
and the toolbar array can contain system buttons.
範例
var cancelButton = Ti.UI.createButton({ systemButton: Ti.UI.iPhone.SystemButton.CANCEL });
訂閱:
文章 (Atom)