Appcelerator Titanium Advent Calendar 2015 2日目 で書いた、インコ式静岡新聞の技術的なお話になります。こんにちは。
さて、インコ式静岡新聞はとてもシンプルなアプリではありますが、なかなか細かなテクニックがいくつか詰まっていますので、それのご紹介をしていければと思います。まあ多分 Objective-C や Java なら簡単にできるよ!といったこともいくつかあるとは思いますが、ぼくは JavaScript が大好きなので、あえて茨の道になってしまうかもしれませんが Titanium なのです。
透明なナビゲーションバーを作る
以前、こちらの投稿 で書きましたが、それのフォローアップ版だと思っていただければ。
Ti.UI.Window
の barColor
に transparent
を指定したり、barImage
に透過画像を指定してもナビゲーションバーに影のボーダーが残ってしまうのでは、hideShadow
を true
にすることで回避できると以前の投稿で書きました。ただ、これだけですと、透明になったナビゲーションバーの存在は残ってしまいます。ここに Ti.UI.TableView
等のリスト系 UI パーツを配置してスクロールすると、ナビゲーションバーが存在する場所でリストが途切れてしまいます。そんなときは、あわせて extendEdges
プロパティを指定してあげましょう。[ Ti.UI.EXTEND_EDGE_TOP ]
を指定することで、ナビゲーションバーを残したままリストが途切れることなく表示することができます。
extendEdges
は、translucent
プロパティを true
にした際、ナビゲーションバーに擦りガラス効果をつけた際、リストをナビゲーションバーの下までスクロールした際に表示させて、滲んだような表示をしてくれます。今回は透明なナビゲーションバーなので、そのまま表示されているように見えますね。
Ti.UI.ScrollableView を縦にスクロールさせる
この UI パーツは通常、横にしかスクロールさせることができません。iPhone のホーム画面なんかがこれになりますね。インコ式静岡新聞では、ニュースを表示している画面で使っています。
簡単なことですが、Ti.UI.2DMatrix
の rotate
メソッドで 90 度回転します。これだけですと、中に追加された UI パーツまで回転してしまうので、追加された親の UI パーツを今度は -90 度回転します。これで見た目もバッチリですね。Ti.UI.ScrollableView
自体の width
と height
は、それぞれ width
には Ti.Platform.displayCaps.platformHeight
を、height
には Ti.Platform.displayCaps.platformWidth
指定してあげてください。Android の場合は Ti.Platform.displayCaps.logicalDensityFactor
の考慮も忘れずに。
インコの着せ替え
お察しの通り、Ti.UI.ScrollableView
が三段構えになっております。画像自体は画面サイズいっぱいになっているので、top
、width
/ height
それぞれを良い感じの座標やサイズで区切ってあります。これを、各画面サイズ分設定ファイルに持っていて、起動時に画面サイズから算出しています。
地味な作業でしたが、これが一番きついかもしれませんね。Android とか Android とか Android とか...。
時計
アプリホーム画面の時計、ありますよね。これ、長針と短針がじみーーーに動いているの、知っていました?針を動かすアルゴリズムはネットにありますのでググってみてください。
この時計は皆さん大好きな setInterval
で動かしています。はい、危険な香りがしてきましたね。大丈夫です。手厚くフォローしてあげれば怖くないです。やりっぱなしにするのが悪いんです。
どんなフォローかといいますと、画面が遷移した際にタイマーを停止しています。clearInterval
ですね。実は画面が遷移したとしても setInterval
が勝手に停止するかというと、そうではありません。自分で止めてあげないといけません。なので、setInterval
するときは、必ず戻り値のタイマー ID を保持してください。回しっぱなしにするのがいけません。
もちろん、アプリがバックグラウンドに移行した際も停止してあげてください。レジュームイベントで、また動かしてあげれば良いだけです。setInterval
する際のお約束ですよ。
その他、細かなお約束とか
コントローラに、Ti.UI.create〜 しない
ぼくは絶対にしません。必ず別のビューコントローラを作ります。なぜかというと、歯止めが効かなくなるからですね。確かに楽なのですが、本当にやりたい放題になってしまいますので...。そして、クラシックスタイルのコードはあれだけ見づらい見づらいと言われてきて、せっかく Alloy が登場したのにまた昔へ逆戻りとか、ちょっと考えられません。自ら見づらいコードを書くなんて墓穴は掘らないですよ。
ただ、Ti.UI.2DMatrix / 3DMatrix
は別ですよ。これはコントローラに直書きしないと無理ですし、これを多用するなら、その部分は Widget 化します。ん?Ti.UI.AttributedString
できないって?いやだなあ、これは Alloy で書けますよ。どこかの誰かがビューとスタイルで書けるようにしてくれたんです(自慢)。
JSHint、JS Beautifier を忘れない
JSHint はもう当たり前ですね。できることなら JS Beautifier もしちゃいましょう。綺麗なコードを保つ。これ、大事です。
さらに Titanium Style Sheets、これも汚くなりがちです。そこで tssfmt をご用意しました。cssfmt みたいなやつですね。その昔、tss-formatter というものがありました(cssfmt よりも前なんですよ!)。fmt って省略するのが流行りっぽいので名前を変えてフルスクラッチしたものです。Alloy に依存しないようにしたりと、内部は別物なんですけどね。
tssfmt はプロパティの順序まで強制することができます。top
や left
プロパティがクラスによって順序がバラバラなんて、ストレスでしかありません。こんなところで気を使うくらいなら、別のところで集中したいですもんね。今ならなんと、tssfmt の gulp プラグイン までご提供中です。
イベント外そう
使い終わったイベント、ちゃんと外していますか?こういう小さな積み重ねも大事なんですよね。おっと、一つ一つ removeEventListener
が面倒ですか?いやいや、便利なメソッドがあるんですよ。$.removeListener();
してみてください。ビューに onClick
等でイベント処理を記述しておけば、対象コントローラの全てのイベントを一括で解除することができます。どこかの誰かが追加したんですね。簡単でしょ?(自慢)
普通に addEventListener
した場合は対象にならないので、気をつけてください。コントローラ内で別途イベントを追加したい場合は、$.addListener
メソッドが用意されています。このメソッドを使えば対象になりますので、こちらを使ってください。
まとめ
文字ばかりになってしまいましたが、24 日はもっと文字が増えると予想されます。テストですからね。カバレッジのスクショくらいは貼り付けて盛り上げたいですね。それでは。