#freeze
[[FrontPage]]

#contents

2011/07/31からのアクセス回数 &counter;

** テーブルビューの表示 [#e00e3ae5]
[[titanium/はじめの一歩]]の次は、よく使うテーブルビューを表示することにします。
テーブルには、体重と測定日付を表示することにします。

何事もものまねからはじまります。
[[Titanium Mobileで作る! iPhone/Androidアプリ第2回>http://gihyo.jp/dev/serial/01/titanium/0002]]
から、TableViewの表示部分を参考にtable_view.jsを作成します。

最初にテストデータをセットします。

table_view.js(先頭のデータセット部分)
#pre{{
var records = [{
		weight: 60.3,
		at: new Date('Jul 25 2011')},
	{
		weight: 62.5,
		at: new Date('Jul 26 2011')
}];
}}

TableViewの作成は以下のようになります。
#pre{{
var win = Ti.UI.currentWindow;
var data = [];
var tableView = Ti.UI.createTableView({
	data:data
});
win.add(tableView);
}}

- Ti.UI.currentWindowでこの画面のWindowを取得します
- dataは、TableViewに渡すリスト項目をセットします(最初は空の配列)
- 生成されたTableViewはすぐにwinに追加しましょう(忘れないように)

TableViewへの行データの追加は、以下のようにします。

#pre{{
function updateRecord (records) {
	var data = currentData = [];
	for (var i=0;i<records.length;i++) {
		var record = records[i];
		var row = Ti.UI.createTableViewRow({
			height: 'auto',
			layout: 'vertical',
			hasChild: true,
		});
		var weightLabel = Ti.UI.createLabel({
			width: 50,
			height: 'auto',
			left: 5,
			top: 5,
			fontSize: 8,
			fontWeight: 'bold',
			textAlign: 'right',
			color: '#2b4771'
		}
		);
		weightLabel.text = record.weight;
		row.add(weightLabel);
		var weightUnit = Ti.UI.createLabel({
			width: 50,
			height: 'auto',
			left: 60,
			top: -weightLabel.height,
			fontSize: 8,
			fontWeight: 'bold',
			text: 'Kg',
			color: '#2b4771'
		}
		);
		row.add(weightUnit);
		var dateLabel = Ti.UI.createLabel({
			width: 290,
			height: 'auto',
			left: 5,
			top: 5,
			fontSize: 6,
			textAlign: 'right'
		}
		);
		dateLabel.text = record.at.toDateString();
		row.add(dateLabel);

		currentData.push(row);
	}
	tableView.setData(currentData);
}
updateRecord(records);
}}

- TableViewRowを生成し、これに部品(ラベル)を追加します
- tableViewに生成したリスト項目をセットします
- 最後にupdateRecordを呼び出し、レコードの更新を実行します

また、app.jsのwin1のurlもtable_view.jsに変更しておきます。

app.jsの変更
#pre{{
var win1 = Titanium.UI.createWindow({  
	url: 'table_view.js',
    title:'Tab 1',
    backgroundColor:'#fff'
});
var tab1 = Titanium.UI.createTab({  
    icon:'KS_nav_views.png',
    title:'Tab 1',
    window:win1
});
}}

*** 動かしてみる [#t593ff48]
表示プログラムが完成したので、実行してみます。

&ref(tableView.png);

** テーブルビューの編集 [#tfbdfbb2]
テーブルビューの表示ができたところで、リスト項目を編集できるようにします。

** リスト項目の削除 [#m89b00d0]
TableViewには、editableという属性があり、これをtrueにすることによってスワイプ(リスト項目上で左から右に動かす)すると「削除」ボタンが現れます。これをクリックすると該当するリスト項目が削除されます。

&ref(delete.png);

createTableView部分の修正
#pre{{
var tableView = Ti.UI.createTableView({
	data:data,
	editable: true
});
}}

これで、リスト項目が削除されるのは確認できましたが、これでは内部のレコード情報recordsが更新されていません。

そこで、TableViewのコールバック関数を定義して、リスト項目が削除された時にその情報を取得する処理を追加します。人の好みですが、私はコールバック関数の定義とその組み込み場所を分けて書きます。
((画面定義部と処理部を分かりやすくするため))

削除処理部
#pre{{
function deleteCallback(index) {
	records.splice(index, 1);
	updateRecord(records);
}
}}

tableViewへのコールバック定義部
#pre{{
tableView.addEventListener('delete', function(e){
	deleteCallback(e.index);
});
}}

** リスト項目の追加 [#tfa262d2]
次にリスト項目の新規追加ができるようにします。
新規追加というとデータを入力する画面が必要になります。

そこで、2つのTextFieldと1つのボタンを持つ簡単な入力画面を作成します。

&ref(input_record.png);

これをrecord_window.jsに作成します。

record_window.jsの内容
#pre{{
var win = Ti.UI.currentWindow;

var dateField = Ti.UI.createTextField({
	hintText: '日付を入力してください',
	top:20, left:50, right:50, height:40,
	borderStyle: Ti.UI.INPUT_BORDERSTYLE_ROUNDED
});
win.add(dateField);

var weightField = Ti.UI.createTextField({
	hintText: '体重を入力してください',
	top:80, left:50, right:50, height:40,
	borderStyle: Ti.UI.INPUT_BORDERSTYLE_ROUNDED
});
win.add(weightField);

var saveButton = Ti.UI.createButton({
	title: 'この値で保存する',
	top:140, left:50, right:50, height:40
});
win.add(saveButton);
}}

画面を作成した場合に簡単に確かめる方法は、app.jsのwin2を使うと便利です。

app.jsのwin2の変更部分
#pre{{
var win2 = Titanium.UI.createWindow({  
	url: 'record_window.js',
	title:'Tab 2',
	backgroundColor:'#fff'
});
}}

画面が正しく表示できることを確認したら、テーブルビューにリスト項目追加のボタンを追加します。

table_view.jsに以下を追加
#pre{{
var addButton = Ti.UI.createButton({
	systemButton: Titanium.UI.iPhone.SystemButton.ADD
});
addButton.addEventListener(
'click', function () {
	var recordWindow = Ti.UI.createWindow({
		url: 'record_window.js',
		backgroundColor:'#fff'
	});
	Ti.UI.currentTab.open(recordWindow);
});
win.rightNavButton = addButton;
}}

&ref(addButton.png);

*** データ入力画面からテーブルビューへのデータ受け渡し [#ied781aa]
新規追加ボタンでデータ入力画面に遷移し、その結果をテーブルビューに反映するにはどうすればよいのでしょう。

ちょっと気持ち悪いですが、Titanium mobileではTi.Appのカスタムイベントを使用します。

record_window.jsの「この値で保存します」ボタンがクリックされた時の処理
#pre{{
saveButton.addEventListener(
'click', function () {
	var record = {};
	record.weight = weightField.value;
	record.at = new Date(dateField.value);
	Ti.App.fireEvent('insert_row', record);
	win.close();
});
}}

- Ti.App.fireEventを使ってカスタムイベントinsert_rowにrecordをセットして送ります

今度は、TableView側でこのイベントを受け取る処理を追加します。

table_view.jsのイベント受け取り処理
#pre{{
Ti.App.addEventListener('insert_row', function(record) {
	Titanium.API.debug("insert_row");
	insertCallback(record);
});
}}

リスト項目追加の処理
#pre{{
function insertCallback(record) {
	records.push(rerod);
	records.push(record);
	updateRecord(records);
}
}}

*** 追加動作確認 [#g05dd9ec]
iPhoneシミュレータで追加処理の動作を確認してみましょう。

日付の入力は、javascriptのDate型が認識できるように Jul. 31 2011と入力します。

&ref(add_record.png); &ref(add_list.png);

** リスト項目の更新 [#r6016120]
最後にリスト項目の値を更新する処理を追加します。

更新に際し、どのレコードを更新するか分かるようにrecordにindexを追加します。
また処理が「追加」、「更新」のいずれかわかるようにfuncにカスタムイベント名をセットします。

*** テーブルビューから編集画面へのデータの受け渡し [#s80b9e55]
テーブルビューから編集画面へのデータ受け渡しは、createWindowの引数に追加するだけで行えます。
リスト項目の編集は、リスト項目がクリックされた時に行います。


table_view.jsにテーブルのリスト項目がクリックされた時の処理
#pre{{
tableView.addEventListener(
'click', function(e) {
	var record = records[e.index];
	record.index = e.index;
	var recordWindow = Ti.UI.createWindow({
		url: 'record_window.js',
		record: record,
		func: 'update_row',
		backgroundColor:'#fff'
	}
	);
	Ti.UI.currentTab.open(recordWindow);
});
}}

追加の場合も同様に変更
#pre{{
addButton.addEventListener(
'click', function () {
	var recordWindow = Ti.UI.createWindow({
		url: 'record_window.js',
		record: {weight:'', at: new Date()},
		func: 'insert_row',
		backgroundColor:'#fff'
	});
	Ti.UI.currentTab.open(recordWindow);
});
}}

また、update_rowイベントを受け取る処理
#pre{{
Ti.App.addEventListener('update_row', function(record) {
	Titanium.API.debug("update_row");
	updateCallback(record);
});
}}

更新処理は、
#pre{{
function updateCallback(record) {
	records[record.index] = record;
	updateRecord(records);
}
}}
とします。

record_window.jsの変更は、
テーブルビューから渡された値をセットするようにTextField部分を変更します。
#pre{{
var dateField = Ti.UI.createTextField({
	value: win.record.at.toDateString(),
	hintText: '日付を入力してください',
	top:20, left:50, right:50, height:40,
	borderStyle: Ti.UI.INPUT_BORDERSTYLE_ROUNDED
});
win.add(dateField);

var weightField = Ti.UI.createTextField({
	value: win.record.weight,
	hintText: '体重を入力してください',
	top:80, left:50, right:50, height:40,
	borderStyle: Ti.UI.INPUT_BORDERSTYLE_ROUNDED
});
win.add(weightField);
}}

また、カスタムイベントを送る処理も以下のようになります。
#pre{{
saveButton.addEventListener(
'click', function () {
	var record = {};
	record.index = win.record.index;
	record.weight = weightField.value;
	record.at = new Date(dateField.value);
	Ti.App.fireEvent(win.func, record);
	win.close();
});
}}

*** 更新の動作確認 [#t1131b63]
更新の動作確認をします。
体重をベスト60.0に変更すると、テーブルビューにきちんと反映されました。

意外に簡単にテーブルビューが使えることがわかりました。

&ref(update_record.png); &ref(update_list.png);

** プログラムソース [#u9c552a0]
ここまでのプログラムソースは、
- &ref(Demo.zip);

にまとめてあります。

** コメント [#v7603c0d]
#vote(おもしろかった[7],そうでもない[0],わかりずらい[1])
#vote(おもしろかった[18],そうでもない[0],わかりずらい[1])

皆様のご意見、ご希望をお待ちしております。
- insertCallback関数のrecords.push(record)のスペルミスを修正しました。 -- [[竹本 浩]] &new{2013-04-09 (火) 16:23:36};

#comment_kcaptcha


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
SmartDoc