FrontPage

2011/08/08からのアクセス回数 4826

Projectファイルの再作成

Android SDKをインストールする前に作成したTitaniumのプロジェクトは、 Resoruceファイル以下をバックアップして、作り直す必要があります。

iPhoneとAndroidの違い

TitaniumのAPIでデバイス依存するもの(「iOSのみ」と表記)を使用した場合、注意が必要です。 特に

  • NavigationGroup
  • TableViewRowの削除等のSwipeイベントに対応する機能
  • HTTPClient(実装が全く異なるためiPhoneとAndroidでの動作確認が必要)

には、デバイス毎に対応する必要があります。

NavigationGroupの対応

iPhoneでよく使われるナビゲーションバーの左右のボタンは、Androidではメニューで代用するため、 実装がことなります。

そこで、以下のnavigation.jsファイルにデバイスの違いを吸収するコードをまとめました。

var Navigation = function() {
	this.setup = function(nav) {
		if (Ti.Platform.osname === 'android') {
			var android = nav.android;
			var activitiy = Ti.Android.currentActivity;
			if (activitiy) {
				activitiy.onCreateOptionsMenu = function(e) {
					var menu = e.menu;
					if (android && android.leftButton) {
						var leftMenuItem = menu.add(android.leftButton);
						leftMenuItem.setIcon(android.leftButton.icon);
						leftMenuItem.addEventListener('click', android.leftButton.callback);
					}
					if (android && android.rightButton) {
						var rightMenuItem = menu.add(android.rightButton);
						rightMenuItem.setIcon(android.rightButton.icon);
						rightMenuItem.addEventListener('click', android.rightButton.callback);
					}
				};
			}
			
		}
		else {
			var win = Ti.UI.currentWindow;
			var iPhone = nav.iPhone;
			if (iPhone && iPhone.leftButton) {
				var leftButton = Ti.UI.createButton(iPhone.leftButton);
				leftButton.addEventListener('click', iPhone.leftButton.callback);
				win.leftNavButton = leftButton;
			}
			if (iPhone && iPhone.rightButton) {
				var rightButton = Ti.UI.createButton(iPhone.rightButton);
				rightButton.addEventListener('click', iPhone.rightButton.callback);
				win.rightNavButton = rightButton;				
			}
		}
	};
};

使用する場合には、各ボタンのコールバック関数を別途定義し、以下のように使用します。

table_view.jsへの変更

var addCallback = function(e) {
	var at = new Date();
	var recordWindow = Ti.UI.createWindow({
		url: 'record_window.js',
		record: {weight:'', at: at.toDateString()},
		func: 'insert_row',
		backgroundColor:'#fff'
	});
	Ti.UI.currentTab.open(recordWindow);	
};

var grpahCallback = function(e) {
	if (records.length > 0) {
		var weights = "[";
		var ticks = "[";
		for (i = records.length-1; i >= 0; i--) {
			var at = new Date(records[i].at);
			weights = weights + "[" + at.getTime() +","+records[i].weight+"],";
			ticks = ticks + at.getTime() + ",";
		} 
		weights = weights + "]"; ticks = ticks + "]";
		var graphWindow = Ti.UI.createWindow({
			url: 'plot_window.js',
			weights: weights,
			ticks: ticks
		}
		);
		Ti.UI.currentTab.open(graphWindow);		
	}	
};

var navi = new Navigation();
navi.setup({
	iPhone: {
		leftButton: {title: 'Graph', callback: grpahCallback},
		rightButton: {systemButton: Titanium.UI.iPhone.SystemButton.ADD, callback : addCallback}
		
	},
	android: {
		leftButton: {title: 'Graph', icon: 'dark_stats-bars.png', callback: grpahCallback},
		rightButton: {title: 'Add', icon: 'dark_add.png', callback : addCallback}		
	}
});

setup関数で、iPhone、androidで使用するボタンのタイトル、アイコン、コールバック関数をセットするだけです。

Androidシミュレータでメニューボタンを押すと、以下のようになります。

android-navigator.png

テーブル項目の削除

iPhoneでのTableViewRowでのSwipeで削除する機能が使えないため、record_window.jsに削除メニューを追加することにしました。navigation.jsにデバイスの違いを吸収したので、Androidへの削除メニューの追加もとてもシンプルです。

record_window.jsの追加

var deleteCallback = function(e) {
	Ti.App.fireEvent('delete_row', win.record);
	win.close();
}; 

Ti.include('navigation.js');
var navi = new Navigation();
navi.setup({
	android: {
		rightButton: {title: 'Delete', icon: 'dark_x.png', callback : deleteCallback}		
	}
});

次にtable_view.jsでdelete_rowイベントを処理する部分を追加します。

table_view.jsの変更(deleteCallbackも変更しました)

function deleteCallback(record) {
	db.deleteOne(record);
	records = db.findAll();
	updateRecord(records);
}
tableView.addEventListener('delete', function(e){
	deleteCallback(records[e.index]);
});
Ti.App.addEventListener('delete_row', function(record) {
	Titanium.API.debug("delete_row");
	deleteCallback(record);
});

record_window.jsの画面は、以下のようになります。

android-delete.png

WebViewのログイン処理

iPhoneでは、すべてのアプリケーションでCookieを共有するため、FoodLogのようにCookieを使ってユーザ認証をするサイトの場合、HTTPClientでログインすれば良かったのですが、AndroidではWebView単位でユーザ認証するしなければなりません。*1

FoodLogでは、

  • FoodLogではjQueryを使用しているので、evalJSを使って認証処理をします
  • /account/loginページで認証をすると、/myfood/listに画面遷移します
  • 既に認証が終わっていたら、/に画面遷移します

これで、iPhone、Androidのどちらの場合も動作します。

foodlog_window.jsを以下のように変更します。

// FoodLogのWebページを表示
win = Ti.UI.currentWindow;
var webView = Ti.UI.createWebView({
	url: 'http://www.foodlog.jp/account/login/'
}
);
webView.visible = false;
win.add(webView);
webView.addEventListener('load', function(){
	var href = webView.evalJS('window.location.href');
	// ログイン処理
	if (href == 'http://www.foodlog.jp/account/login/') {
		webView.evalJS('$(login_account_code).val("あなたのユーザID");');
		webView.evalJS('$(login_password).val("あなたのパスワード");');
		webView.evalJS('$("input[name=commit]").click();');		
	}
	// /calendarに移動
	else if (href == 'http://www.foodlog.jp/myfood/list' || href == 'http://www.foodlog.jp/') {
		webView.evalJS('window.location="http://www.foodlog.jp/calendar";');		
	}
	// ウィンドウを表示
	else {
		webView.visible=true;
	}
});

最後にAndroidでのFoodLogのカレンダー画面をご覧頂きます。

android-foodlog.png

プログラムソース

ここまでのプログラムソースは、

にまとめてあります。

コメント

選択肢 投票
おもしろかった 2  
そうでもない 0  
わかりずらい 1  

皆様のご意見、ご希望をお待ちしております。

  • navigation.jsのiPhone, android変数チェック漏れのバグを修正 -- 竹本 浩? 2011-08-16 (火) 13:17:49

(Input image string)


*1 ここが最も苦労したところ

添付ファイル: fileDemo.zip 407件 [詳細] fileandroid-foodlog.png 559件 [詳細] fileandroid-delete.png 452件 [詳細] fileandroid-navigator.png 549件 [詳細]

トップ   編集 凍結解除 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2011-11-11 (金) 18:49:21 (2052d)
SmartDoc