Amazon

2012年5月19日土曜日

TitaniumのaddEventListenerでハマる

TitaniumでTableViewRowにテキストや写真を追加して、各要素をクリックするとそれぞれのアクションを起こしたいとする。
このとき、各要素にaddEventListenerを追加することでアクションを拾ってもらうようにコードを書いてしまいがちだが、上手く行かない。
例えば、以下のコードでは、TableViewRowである変数rowに、photo, name, updateTime, textを追加しており、TableViewの行およびphotoをクリックすると、それぞれのJavaScriptファイルが別Windowで読み込まれるというもの。
この時、ハマったのはrowのaddEventListenerでpost.idを別Windowのwinに渡そうとしても上手く渡らなかった


var win = Ti.UI.currentWindow;
var tableView = Ti.UI.createTableView({
 top : 50
});
win.add(tableView);

Ti.Facebook.requestWithGraphPath('me/home?date_format=r&limit=5', {}, 'GET', function(e) {

 if(e.success) {
  var result = JSON.parse(e.result);
  var data = result.data;
  tableView.setData([]);
  for(var i = 0; i < data.length; i++) {
   var post = data[i];
   var row = Titanium.UI.createTableViewRow({
    layout : 'vertical',
    height : 'auto',
    postId : post.id,
   });
   row.addEventListener('click', function(e) {
    var win = Titanium.UI.createWindow({
     postId : this.postId,
     url:'./row.js',
    });
    Titanium.UI.currentTab.open(win, {
     animated : true
    });
   });
   
   var photo = Titanium.UI.createImageView({
    image : 'http://graph.facebook.com/' + post.from.id + '/picture?type=square',
    width : 50,
    height : 50,
    top : 5,
    left : 5,
    borderRadius : 5,
    postId : post.id,
   });
   photo.addEventListener('click', function(e) {
    var win = Titanium.UI.createWindow({
     postId : this.postId,
     url:'./photo.js',
    });
    Titanium.UI.currentTab.open(win, {
     animated : true
    });
   });
   
   var name = Titanium.UI.createLabel({
    text : post.from.name,
    top : -50,
    width : 200,
    height : 30,
   });
   
   var updateTime = Titanium.UI.createLabel({
    text : Date.parse(post.created_time),
    width : 200,
    height : 25,
   });
   
   var text = Titanium.UI.createLabel({
    text : post.message,
    top : 'auto',
    height : 'auto',
   });
   
   row.add(photo, name, updateTime, text);
   tableView.appendRow(row);
  }
 }
});



みたいなコードを書いてしまうが、どうもEventListnerが複数あると、上手くイベントをハンドルできなくなるようです。 そんなわけで、EventListenerはTableViewに一つ登録しておき、TableViewのイベントで、クリックされた行を検知して、その行にセットしておいた変数(ここではextというオブジェクトリテラルを各要素に定義)別に処理を返るという方法を採用した。
var win = Ti.UI.currentWindow;
var tableView = Ti.UI.createTableView({
 top : 50
});
tableView.addEventListener('click', function(e) {
 var postId = e.rowData.postId;
 var type = (e.source.ext) ? e.source.ext.type : "";
 if(type === "photo") {
  var win = Titanium.UI.createWindow({
   url:'./photo,js',
   postId : postId,
  });
  Titanium.UI.currentTab.open(win, {
   animated : true
  });
 } else {
  var win = Titanium.UI.createWindow({
   url:'./row.js',
   postId : postId,
  });
  Titanium.UI.currentTab.open(win, {
   animated : true
  });
 }

});
win.add(tableView);

Ti.Facebook.requestWithGraphPath('me/home?date_format=r&limit=5', {}, 'GET', function(e) {

 if(e.success) {
  var result = JSON.parse(e.result);
  var data = result.data;
  tableView.setData([]);
  for(var i = 0; i < data.length; i++) {
   var post = data[i];
   var row = Titanium.UI.createTableViewRow({
    layout : 'vertical',
    height : 'auto',
    postId : post.id,
   });
   
   var photo = Titanium.UI.createImageView({
    image : 'http://graph.facebook.com/' + post.from.id + '/picture?type=square',
    width : 50,
    height : 50,
    top : 5,
    left : 5,
    borderRadius : 5,
    postId : post.id,
    ext:{
     type:'photo',
    },
   });
   
   var name = Titanium.UI.createLabel({
    text : post.from.name,
    top : -50,
    width : 200,
    height : 30,
   });
   
   var updateTime = Titanium.UI.createLabel({
    text : Date.parse(post.created_time),
    width : 200,
    height : 25,
   });
   
   var text = Titanium.UI.createLabel({
    text : post.message,
    top : 'auto',
    height : 'auto',
   });
   
   row.add(photo, name, updateTime, text);
   tableView.appendRow(row);
  }
 }
});

こちらを参考にしました。

0 件のコメント:

コメントを投稿

Amazon3