最近のTitanium
つい先日(6月13日)にTitanium Mobile 1.7がリリース され、Android開発に便利な機能がいくつか増えました。特にFastdev for Androidという、コードの変更を高速にエミュレータに反映する機能はAndroid開発をかなり加速してくれそうです。この機能については今回の記事の後半で解説します。また今回は解説しませんが、Titanium Stduioという統合開発環境も正式版が発表になり、今後はTitainum Developerからこちらに移行されていくことが表明されています。
デバイスごとのUIデザイン
さて、前回 の記事でなんとかAndroidでもTwitter Clientが動作するようになりました。HVGAの解像度を指定してエミュレーター実行すると調度よいデザインで表示されます。しかしWVGA800やWVGA854といった解像度で表示すると、解像度がかなり大きいためデザインがくずれたり、相対的に文字が小さく表示されるようになって表示が見にくくなったりと不都合がでてきます。今回はこの、デバイスごとにUIデザインをどうにかする方法を解説します。
図1 高解像度では若干デザインが崩れる
JSS
TitaniumではUIのデザインとロジックを切り分ける方法の一つとして、JSS(JS Stylesheets)が用意されています。これはCSSと似たような記法でUI部品のwidth, heightといったプロパティを書いておくことでUIのデザインを共通化し、また別ファイルにすることができるものです。次のようなルールで適用されます。
ファイル名はwindow_js_name .jss
ファイルは何処にあっても上のルールが適応される
idかclassを指定してデザインの指定を書く
記法はcssとほとんど同じ
ファイル名にあるwindow_js_nameのところは、自分がUI部品をデザインしたいWindowの定義をしているjavascriptのファイル名(拡張子は除く)です。つまりサンプルアプリでツイート一覧を表示しているtable_view.jsのデザインをしたい場合はtable_view.jssというファイルを用意します。このファイルはResources以下のどのディレクトリにあっても適応されるので注意が必要です。
また、CSSの記法では、tagを指定したり色々なセレクタがありますが、JSSではクラス名かidを指定します。各UIオブジェクトにもクラス名かidを割り振ることで適応されるJSSが決まります。ということで、サンプルコードを見てみましょう。
table_view.js
function updateTimeline ( timeline ) {
var currentData = [];
for ( var i = 0 ; i < timeline . length ; i ++) {
var tweet = timeline [ i ];
var row = Ti . UI . createTableViewRow ({ id : 'row' });
var imageView = Ti . UI . createImageView (
{
image : tweet . user . profile_image_url ,
className : 'tweetIcon'
}
);
row . add ( imageView );
var nameLabel = Ti . UI . createLabel ({ id : 'nameLabel' });
nameLabel . text = tweet . user . screen_name ;
row . add ( nameLabel );
var commentLabel = Ti . UI . createLabel ({ id : 'commentLabel' });
commentLabel . text = tweet . text ;
row . add ( commentLabel );
var dateLabel = Ti . UI . createLabel ({ id : 'dateLabel' });
dateLabel . text = tweet . created_at ;
row . add ( dateLabel );
currentData . push ( row );
}
tableView . setData ( currentData );
まずは、JSのコードからです。この部分はタイムラインのツイートに含まれるユーザー名や日付の情報をラベルにして、TableViewのrowとして追加しているところです。 今まではTi.Ui.createLabelなど画面部品を作成しているところで、直接widthやheightを渡していましたが、このコードではそういったデザイン要素がなくなり、代わりにidプロパティが指定されています。全体としてデザインのためのコードがほとんどなくなりコードが見やすくなっています。
そして、ここで指定されているidごとにデザインを指定しているのが、このtable_view.jsに対応するtable_view.jssです。
table_view.jss:一部抜粋
# row {
height : 'auto' ;
layout : 'vertical' ;
}
. tweetIcon {
width : 48 ;
height : 48 ;
top : 5 ;
left : 5 ;
}
# nameLabel {
width : 120 ;
height : 'auto' ;
left : 58 ;
top : - 48 ;
fontSize : 6 ;
fontWeight : 'bold' ;
color : '#2b4771' ;
}
cssとほぼ同様の書き方ができ、#rowのように # から始めるセレクタはidを示し、.tweetIconのように . で始まるセレクタはクラスを示しています。各プロパティは今までTi.UI.createLabelに渡していたものと同じです。当然ですが、JSのオブジェクトではないので各プロパティはカンマ区切りではなく、セミコロンで区切るようにする必要があります。一方でfontSizeはfont-sizeと書くべきなのがCSSのルールのように思えますが、これはどちらで書いても有効になります。しかしfontSizeと書いた場合とfont-sizeと書いた場合で基準となる単位が変わるようなので注意が必要です。
classNameでの指定はCSSと同様に複数のクラスを指定できて便利なのですが、classNameで指定するとAndroidで上手く動かないバグも報告されている ので、うまく指定できないときはidで指定するとよいでしょう。
端末ごとに異なるJSSを利用する
さてJSSについて紹介してきましたが、今回の記事の目的は解像度が異なるデバイスごとに異なるデザインを当てる方法について解説することでした。そこでこのJSSが活躍してくれます。先程の例ではtable_view.jsに対してtable_view.jssを用意しましたが、Androidの端末サイズごとに異なるJSSが用意できるのです。具体的には
table_view.android.low.jss
table_view.android.medium.jss
table_view.android.heigh.jss
の3つを用意することができ、解像度にあわせてそれぞれのJSSが選択されます。よって想定される端末ごとに、この3つのJSSファイルを書くことで、ロジックのコードに手を入れずに複数端末に対応することができます。ファイル名のルールは見たままですが、今までと同じように、
Windowの定義が書いてあるJSのファイル名 .android.サイズ .jss
というようになります。
low, medium, heighの閾値はTitanium側というよりはAndroidのAPIで規定されるもののようで、ディスプレイのdpiの値によって決められます。
などを参考にしてください。
また、今回Android開発の流れの中でJSSについて紹介しましたが、JSSはiOSアプリでも有効です。
FastDev を使ってみる
JSSについての話は以上にして、ここからは少し毛色のちがうFastDevというエミュレーターへの反映方法について解説します。
FastDevはJSへの変更をリビルドなしにエミュレータに反映できるので、非常に高速に、コードの変更とテストを繰り返すことができます。つまりコードに変更を加えると即座にその変更を確認できるようになります。もしエミュレータがそれなりの速度で動く環境であれば、iPhone開発と近い感覚で(あるいはもっと高速に)開発ができます。
この機能はTitanium 1.7.0からの機能なので、かならずTitanium Mobile SDKを最新にバージョンアップしておいてください。
では実際の使い方です。まず、準備としてtitaniumコマンドをターミナルから呼び出せるようにする必要があります。以下、bashをターミナルで利用している前提で解説していきます。titaniumコマンドはTitanium Mobile SDKのあるディレクトリに含まれているので、次のようなaliasを.bashrcに記載します。
alias titanium = '/Library/Application\ Support/Titanium/mobilesdk/osx/1.7.0/titanium.py'
これでtitainumコマンドが呼び出せるようになったので、ターミナルを開いて次のコマンドを入力します
titanium fastdev start &
これでコードの管理を行うサーバーが起動します。次に、通常の方法で開発中のアプリを起動します。つまりTitanium DeveloperのRun EmulaterタブにあるAndroidタブからLaunchをクリックします。そして、無事アプリが起動したら、
titanium run --platform=android --android=/path/to/android-sdk
と入力します。/path/to/android-sdkはこの連載に書いてある手順に従っていれば、/Users/YOURNAME /AndroidSDKになります。かなり時間がかかりますが、もう一度アプリが起動すれば準備完了です。
これ以降はコードに変更を加えると、変更があったWindowを開いたタイミングで新しいコードが読み込まれるようになります。app.jsへの変更や、Ti.includeを使って読み込んだファイルの変更は読み込まれないので、
titanium fastdev restart-app
というコマンド入力してリスタートする必要があります。このコマンドでも反映されないときは、再度
titanium run --platform=android --android=/path/to/android-sdk
と入力すると全体がリビルドされるので上手くいく可能性が高くなります。
また、今回の記事の前半で解説したJSSの機能もjavaのソースファイルを書きだすことで実装されているので、残念ながらtitanium runコマンドで再度ビルドしないと反映ができません。
この機能の詳しいドキュメントはhttp://wiki.appcelerator.org/display/guides/Fastdev+Reference+for+Android にあります。