今回はTitaniumのモジュール機能を利用してカスタムViewを作ります。
最低限必要な手順を整理したかったので、カスタマイズ内容は通常のViewクラスに色をつけるだけのシンプルな内容にしました。
プロジェクトの作成
TitaniumのAndroid用モジュールを作る その1の手順に従って、モジュールのテンプレートプロジェクトを作成します。
titanium create --platform=android --type=module --name=ColoredView --id=net.siso9to.coloredview --android=$HOME/devel/android-sdk-mac_x86
作成したテンプレートプロジェクトをeclipseにimportするとモジュール作成の準備完了です。
モジュールの作成
importしたプロジェクトのパッケージディレクトリの下に、ColoredviewModule.javaとExampleProxy.javaという2つのファイルがあります。
このままでも問題ありませんが、モジュールの方は名前がキャメルケースになっておらず少し気持ち悪いのでColoredViewModule.javaにリファクタします。
@Kroll.module(name="Coloredview", id="net.siso9to.coloredview")
のnameの値はリネームされないので、ここは手動で変更します。
また、不要なメソッドやコメントも削除し、ExampleProxy.javaも今回は作りなおすので削除します。
修正したColoredViewModule.javaは以下のようになります。
package net.siso9to.coloredview; import org.appcelerator.kroll.KrollModule; import org.appcelerator.kroll.annotations.Kroll; import org.appcelerator.titanium.TiContext; @Kroll.module(name="ColoredView", id="net.siso9to.coloredview") public class ColoredViewModule extends KrollModule { public ColoredViewModule(TiContext tiContext) { super(tiContext); } }
最低限必要な記述のみ残したモジュールが出来ました。
カスタムViewの作成
次にカスタムViewクラスを作成します。
カスタムViewを作成するには、TiUIViewを継承したクラスを作成します。
また、ネイティブのViewをカスタマイズする場合はこのTiUIViewサブクラスの中でネイティブViewのインスタンスを生成し、setNativeViewを呼び出してTiUIViewサブクラスに保持します。
package net.siso9to.coloredview; import org.appcelerator.titanium.proxy.TiViewProxy; import org.appcelerator.titanium.view.TiUIView; import android.content.Context; import android.graphics.Color; import android.view.View; public class ColoredView extends TiUIView { public class CostomView extends View { public CostomView(Context c) { super(c); this.setBackgroundColor(Color.GREEN); } } public ColoredView(TiViewProxy proxy) { super(proxy); CostomView costomView = new CostomView(proxy.getContext()); setNativeView(costomView); } }
Proxyの作成
最後に、作成したカスタムViewをモジュールから呼び出すためにProxyクラスを作成します。
カスタムViewを呼び出すProxyを作成するにはTiViewProxyを継承し、TiUIViewの新しいインスタンスを返すTiUIView createView(Activity activity)をImplementsします。
package net.siso9to.coloredview; import org.appcelerator.kroll.annotations.Kroll; import org.appcelerator.titanium.TiContext; import org.appcelerator.titanium.proxy.TiViewProxy; import org.appcelerator.titanium.view.TiUIView; import android.app.Activity; @Kroll.proxy(creatableInModule=ColoredViewModule.class) public class ColoredViewProxy extends TiViewProxy { private ColoredView coloredView; public ColoredViewProxy(TiContext tiContext) { super(tiContext); } @Override public TiUIView createView(Activity activity) { coloredView = new ColoredView(this); return coloredView; } }
コンストラクタでsetBackgroundColor(Color.GREEN)してネイティブViewに色をつけています。
また、Proxyクラスを作成する際は以下のようにアノテーションのcreatableInModuleの値をモジュール名と一致させる必要があるので注意してください。
@Kroll.proxy(creatableInModule=ColoredViewModule.class)
動作確認用スクリプトの作成
それでは作成したモジュールを動かしてみましょう。
モジュールの動作を確認するためにTitaniumプロジェクトにモジュールを組み込む必要はなく、exampleフォルダ内のapp.jsを使用してモジュールを動かす事が出来ます。
titaniumコマンドで生成されたexample/app.jsを修正し、以下のように記述します。
var window = Ti.UI.createWindow({ backgroundColor:'white' }); var label = Ti.UI.createLabel(); window.add(label); window.open(); var module = require('net.siso9to.coloredview'); Ti.API.info("module is => " + module); var view = module.createColoredView({ top: '100dp', width : '100dp', height : '100dp', color: '#000', }); window.add(view);
なおモジュールからProxyを介してカスタムViewを呼ぶ際はProxyのcreateViewを直接呼ぶわけではなく、上記のように
create + Proxy名から「Proxy」を抜いた文字列
とする必要があるようです。
これに関しては明示的にドキュメントに記述しているものが見つからなかったので他にも命名ルールがあるかもしれません。また何度か別の名前でProxyを作成した際にうまくJavascriptから呼び出せなかったケースもあったので、使用不可の文字列もあるのではないかと思います。(Tiなど?)
動作確認用スクリプトの実行
app.jsの修正が出来たら、antを使用してスクリプトを実行します。
build.xmlで右クリックし、「Debug As」 > 「2 Ant Build...」を選択します。
Antのターゲット一覧が表示されるので、「clean」と「run」を選択します。
※runのみで実行出来ますが不要なファイルが残っているとビルドに失敗する場合があるので最初にcleanを実行しておく方がよいでしょう
「Debug」を押して実行するとエミュレーターが起動し、以下のように表示されました。
緑色の部分が今回作成したカスタムViewです。
作成したモジュールをTitaniumに組み込むにはAntのターゲットをdistにして実行し、生成したzipファイルをTitaniumのプロジェクトにコピーする必要がありますが、詳しくは公式ドキュメントか以前の記事を参照してください。
今回はカスタムViewを作成するための最低限の手順を試してみましたが、titaniumのソースを見ているともう少し複雑なカスタムViewを作成するためには他にも細かなルールがありそうです。
Titaniumはドキュメントが少ない印象がありますがAndroid関連は特に少ないように思うので、早く整備されるといいですね。