2

我正在使用Titanium SDK 3.1.3並將合金項目部署到Android。 我有叫用戶配置這樣的xml文件的窗口:如何修復使用Android中的鈦合金在桌面視圖中消失的觸摸事件和圖像?

<Alloy> 
    <Window class="container"> 

     <View id="MainHolder"> 

      <View id="MainHolderTitleView"> 

       <View id="CloseButton"> 
        <Label id="CloseButtonLabel"></Label> 
       </View> 
       <Label id="MainHolderTitleLabel"></Label> 
       <View id="CreatePostButton"> 
        <ImageView id="CreatePostButtonImage" image="/images/menu_options.png"></ImageView> 
       </View> 
      </View> 

      <View id="AppSettings"> 

       <View id="AppOptionButtons"> 
        <View id="MenuOption1" class="optionButton"> 
         <Label id="Option1Label" class="optionButtonLabel"></Label> 
        </View> 
        <View id="MenuOption2" class="optionButton"> 
         <Label id="Option2Label" class="optionButtonLabel"></Label> 
        </View> 
        <View id="MenuOption3" class="optionButton"> 
         <Label id="Option3Label" class="optionButtonLabel"></Label> 
        </View> 

       </View> 

      </View> 

      <View id="MainHolderWorkspace"> 
       <TableView id="AppTableView"></TableView> 
       <ActivityIndicator id="activityIndicator"/> 
      </View> 

     </View> 

    </Window> 
</Alloy> 

的TSS是這樣的:

".container" : { 
    backgroundColor:"#b1b1b1", 
    width:Ti.UI.FILL, 
    height:Ti.UI.FILL, 
    top:0, 
    left:0, 
    navBarHidden : true 
}, 
"#MenuAppsButton":{ 
    height:'20dp' 
}, 
"#MainHolderTitleLabel":{ 
    // width : '250dp', 
    left : '60dp', 
    right : '60dp', 
    height : '25dp', 
    color:"#FFFFFF", 
    textAlign : 'center', 
    font:{fontSize:'12dp'}, 
    ellipsize : true 
}, 
"#CreatePostButton":{ 
    right:0, 
    width:'44dp', 
    height:'44dp', 
    backgroundColor:"#242424" 
}, 
"#CreatePostButtonImage":{ 
    height:'20dp' 
}, 
".optionButton": 
{ 
    width:Ti.UI.FILL, 
    height:'44dp', 
    backgroundColor:"#f0f0f0", 
    top:1 
}, 
".optionButtonLabel": 
{ 
    color:"#363636", 
    font:{ 
     fontSize:'12dp', 
     fontWeight:"bold" 
    }, 
    height:Ti.UI.SIZE, 
    width:Ti.UI.SIZE 

}, 
"#AppOptionButtons": 
{ 
    width:Ti.UI.FILL, 
    height:Ti.UI.SIZE, 
    backgroundColor:"transparent", 
    layout:"vertical" 

}, 
"#AppSettings": 
{ 
    top:'44dp', 
    left:0, 
    backgroundColor:"transparent", 
    width:Ti.UI.FILL, 
    height:Ti.UI.FILL, 
    layout:"vertical" 
}, 
"#MenuHolder": 
{ 
    width:Ti.UI.FILL, 
    height:Ti.UI.FILL, 
    top:0, 
    left:"-320dp", 
    zIndex:0, 
    backgroundColor:"#363636" 
}, 
"#MainHolder":{ 
    width:Ti.UI.FILL, 
    height:Ti.UI.FILL, 
    top:0, 
    left:0, 
    zIndex:1 
}, 
"#MainHolderTitleView": 
{ 
    left:0, 
    right:0, 
    height:'44dp', 
    top:0, 
    backgroundColor:"#363636", 
    zIndex:0 
}, 
"#MainHolderTitleDraggingView": 
{ 
    left:0, 
    width:'44dp', 
    height:'44dp', 
    top:0, 
    backgroundColor:"transparent", 
    zIndex:2 
}, 
"#MainHolderWorkspace": 
{ 
    top:'44dp', 
    bottom:0, 
    left:0, 
    backgroundColor:"#b1b1b1", 
    zIndex:2 
}, 
"#MainHolderTitleViewMenuButton": 
{ 
    width:'50dp', 
    height:'44dp', 
    left:0, 
    top:0, 
    backgroundColor:"#242424" 
}, 
"#CloseButton": 
{ 
    width:'60dp', 
    height:Ti.UI.FILL, 
    backgroundColor:"#232323", 
    left:0 
}, 
"#CloseButtonLabel": 
{ 
    color:"#FFFFFF", 
    font:{fontSize:'13dp'}, 
    text : L('close_string') 
}, 
"#AppTableView": 
{ 
    width:Ti.UI.FILL, 
    height:Ti.UI.SIZE, 
    top:0, 
    left:0, 
    showVerticalScrollIndicator:true, 
    backgroundGradient : { 
      type : 'linear', 
      colors : [ 
       { 
        color : '#e7e7e7', 
        position : 0.0 
       }, 
       { 
        color : '#d8d8d8', 
        position : 1.0 
       } 
      ] 

    }, 
    separatorColor : 'transparent' 
}, 
"#activityIndicator": 
{ 
    width:Ti.UI.FILL 
} 

在我的tableview我加入兩行用的圖像和20行多用從Web服務獲取的信息,這些行在開始時也包含圖像。每次用戶點擊加載更多視圖時,都會添加20行以上的信息,並從Web服務中獲取信息。

每一行我加是由不同的看法,這取決於內容從Web服務,收到的唯一不變的是在一個XML格式的觀點叫做Stream_Item,看起來像這樣:

<Alloy> 
    <View id="ContainerView" class="container"> 

     <View id="GlobalWorkspace"> 


      <View id="Workspace"> 

       <View id="WorkspacePersonalInfo"> 
        <View id="WorkspaceProfileImage"> 
         <ImageView id="WorkspaceProfileImageView" image="/images/emptyPicture.png"></ImageView> 
        </View> 
        <View id="WorkspaceNameAndDateHolder"> 
         <View id="WorkspaceNameTargetHolder"> 
          <Label id="WorkspaceNameLastName"></Label> 
          <ImageView id="TargetImageView"></ImageView> 
          <Label id="WorkspaceTarget"></Label> 
         </View> 
         <Label id="WorkspaceDate"></Label> 
        </View> 
       </View> 


       <View id="WorkspaceContent"></View> 
      </View> 

     </View> 

     <View id="WorkspaceDecorator"></View> 
    </View> 
</Alloy> 

編輯1 此控制器的代碼如下所示: //將參數傳遞給控制器​​ var args = arguments [0] || {}; //加載腳本來處理圖像緩存 var cacheImage = require('cacheImage'); //是一個簡單還是複雜的條目 var simple = args.simple || 0;

//set values for this controller 
$.WorkspaceNameLastName.text = args.user.name; 
var created_at = args.created_at; 
created_at = created_at.substring(0, created_at.indexOf('T')); 
created_at = created_at.replace('-', '/'); 
created_at = created_at.replace('-', '/'); 
$.WorkspaceDate.text = created_at; 
try 
{ 
    cacheImage('cachedImages_UserImages_Thumb', args.user.avatar.thumb, $.WorkspaceProfileImageView, null); 
} 
catch(error) 
{ 
    Ti.API.info(error); 
} 
//set correct width based on device screen 
var workspaceWidth = Ti.Platform.displayCaps.platformWidth; 
$.GlobalWorkspace.setWidth(workspaceWidth); 
//if user pic is tapped, open profile 
$.WorkspaceProfileImage.addEventListener("singletap", function(e) { 
    Alloy.createController("UserProfile", { 
     peopleObject:args.user 
    }); 
}); 
//arguments for like/dislike controller 
var likenessArgs = { 
    data : args 
}; 
//arguments for text controller 
var textArgs = { 
    id : args.id, 
    text : L(args.action), 
    simple : true, 
    index : args.index, 
    simple : simple 
}; 
//function to get the correct name of the class according to internationalization 
function getClass(e) 
{ 
    switch(e) 
    { 
     case "Group": 
      return L('group_string'); 
     case "Event": 
      return L('event_string'); 
     case "Todo": 
      return L('todo_list_string'); 
     case "TodoTask": 
      return L('todo_string'); 
     case "Album": 
      return L('album_string'); 
     case "AlbumPhoto": 
      return L('photo_string'); 
     case "User": 
      return L('user_string'); 

    } 
} 
//hide target user arrow image 
$.TargetImageView.setOpacity(0); 
//function to open viewer according to class 
function openViewer(type) 
{ 
    switch(type) 
    { 
     case "User": 
      Alloy.createController("UserProfile", { 
       peopleObject : { 
        veramiko_id : args.target.veramiko_id 
       } 
      }); 
     break; 
     case "Event": 
      Alloy.createController("Event_Details", { 
       evento : { 
        veramiko_id : args.target.veramiko_id 
       } 
      }); 
     break; 
     case "Group": 
      Alloy.createController("Group_Profile", { 
       groupItem : { 
        veramiko_id : args.target.veramiko_id 
       } 
      }); 
     break; 
     case "Album": 
      Alloy.createController("PhotoAlbumViewer", { 
       album : { 
        veramiko_id : args.target.veramiko_id 
       } 
      }); 
     break; 
    } 
} 
//arguments for comments controller 
var wall_posts_count = {}; 
wall_posts_count.wall_posts_count = parseInt(args.wall_posts_count); 
wall_posts_count.id = args.id; 
//variable to store attachment controller 
var streamItemImageView; 
//check if data received has a secondary target 
if (typeof args.secondary_target !== 'undefined') 
{ 
    //check if secondary target has a comment 
    if (typeof args.secondary_target.comment !== 'undefined') 
    { 
      //construct the comment according to the context 
     var comment = args.secondary_target.comment; 
     textArgs.text = comment; 
      //check if user target is the same as logged user 
     if(args.target.veramiko_id !== Ti.App.Properties.getObject('loggedUser').user.veramiko_id) 
     { 
      if(args.target.veramiko_id !== args.user.veramiko_id) 
      { 
          //since there's a target display the necessary info for this target and the arrow target image 
       $.WorkspaceTarget.text = args.target.name; 
       $.WorkspaceTarget.width = $.WorkspaceTarget.toImage().width; 
       $.TargetImageView.image = Ti.Filesystem.resourcesDirectory + 'images/targetArrow.png'; 
       $.TargetImageView.setOpacity(1); 
       $.WorkspaceTarget.addEventListener('singletap', function(e){ 
        openViewer(args.target.class); 
       }); 
      } 
     } 
    } 
    //check if there's an attachment 
    if (typeof args.secondary_target.attachment !== 'undefined') 
    { 
      //create attachment controller 
     streamItemImageView = Alloy.createController("Stream_Item_Image", { 
      attachment : args.secondary_target.attachment, 
      comment : args.secondary_target.comment, 
      created_at : args.created_at, 
      updated_at : args.updated_at 
     }).getView(); 
     $.WorkspaceContent.add(streamItemImageView); 
    } 
} 
// since there's no secondary target, it's a text post 
else 
{ 
    var comment = args.target.name; 
    comment = "\"" + comment + "\""; 
    textArgs.text = textArgs.text + ': ' + comment; 
} 
// create like/dislike controller 
var streamItemLikeDislikeView = Alloy.createController("Stream_Item_LikeDislike", likenessArgs); 
// variable for user mentions in post 
var streamItemMentions; 
// check if there's any user mentions in this post 
var mentionsArgs; 
if(typeof args.mentions !== 'undefined') 
{ 
    // since there're user mentions, create the controller and the arguments for it 
    mentionsArgs = { 
     mentions : args.mentions 
    }; 
    streamItemMentions = Alloy.createController("Stream_Item_Mentions", mentionsArgs); 
} 
// create comments controller 
var streamItemCommentsView = Alloy.createController("Stream_Item_Comments", wall_posts_count); 
// callback object with functions that update the comments count 
var callbackObject = {}; 
callbackObject.increaseNumberOfComments = streamItemCommentsView.increaseNumberOfComments; 
textArgs.callbacks = callbackObject; 
// create text controller 
var streamItemTextView = Alloy.createController("Stream_Item_Text", textArgs).getView(); 
$.WorkspaceContent.add(streamItemTextView); 
//if there're user mentions, add the controller 
if(typeof args.mentions !== 'undefined') 
{ 
    $.WorkspaceContent.add(streamItemMentions.getView()); 
} 
// if it's a simple entry add the comments controller 
if(args.simple) 
{ 
    $.WorkspaceContent.add(streamItemCommentsView.getView()); 
} 
$.WorkspaceContent.add(streamItemLikeDislikeView.getView()); 

END EDIT 1

在視圖WorkspaceContent如果已經提出意見或圖像已經附連到入口更視圖添加取決於。

編輯2 而且每Stream_Item控制器包含一個文本控制器和喜歡/不喜歡控制器,這取決於該條目是否具有用戶提及,附接和/或是一個簡單的條目,附加控制器被添加。

我必須明確指出,這個Stream_Item控制器及其添加的控制器在其他Windows中工作得很好,但在這種特定類型的Window上,它變得越來越麻煩。

END EDIT 2

我在Android中遇到的問題是,包含在列的意見觸摸事件被阻止出於某種原因,處理的時候我就已經知道Android上的性能問題使用TableViews並在多個設備上測試之後,除非具有觸摸事件的元素已完成渲染,否則將允許用戶通過觸摸事件與視圖進行交互。這只是一個猜測,但我認爲對我的問題來說很準確。我遇到的另一個問題是,表格行中包含的圖像有時會在滾動或與表格的其他元素進行交互時消失。

我從使用ScrollView切換主要是因爲用於向表視圖添加元素的方法比在ScrollView中找到的方法更實用(即在指定位置插入行以及在ScrollView中找不到這種行爲)。我嘗試了列表視圖,但Alloy中的實現非常混亂,文檔不清楚如何使用其他Alloy視圖動態更改內容。

有沒有辦法解決這些問題?我如何讓圖像停止消失?我怎樣才能繞過這個觸摸塊?

回答

2

我對這個(消失)問題也有非常不好的經驗。由於tableView不是Android的本地元素,因爲它是用於iPhone的,所以Android無法完美處理TableView並創建這些類型的問題。我經歷過這個問題很多次。我建議你使用ListView而不是android的TableView。只有這樣,我才能說你將能夠避免這些問題。併爲觸摸問題。我認爲你需要直接在Elements上使用TouchEvents而不是Views。你如何使用TouchEvents的視圖?

+0

與ListView的問題是,這是一個爛攤子來實現與合金,花費時間後,試圖將其他合金控制器添加到ListView沒有任何成功我離開它,主要是由於時間問題,我還沒有看到一個ListView的例子這可以讓我瞭解如何在Alloy項目中使用它。 –

+0

現在關於我的觸摸事件,添加到TableViewRows的視圖是從合金控制器添加的,如下所示: 'Alloy.createController(「Stream_Item」,entries [i])。getView()' 這個控制器裏面我有代碼看起來像添加到我的問題中的代碼。 該控制器由其自己的Views和其他Alloy控制器組成,具體取決於傳遞給它的數據。 –

+0

你永遠不會在Android上使用tableViews獲得正確的性能......它總是會滯後。你真的需要咬住子彈,並轉移到ListViews –

0

那麼,我仍然有這個問題,我已經從TableView移到ListView,然後再回到TableView。 ListViews比TableViews更平滑,我猜是因爲它們針對模板進行了優化。但ListViews是爲相同大小的內容製作的。我正在開發一個通知應用程序,並且我收到了不同大小的通知,不幸的是我意識到,在更改了所有代碼後,我的所有通知都會在視圖上被截斷。所以我不得不回到桌面,因爲它們允許不同大小的行。

增加性能的另一種方法是在創建TableViewRow時設置className。這樣,行屬性被緩存並用於下一行。但是,如果您需要不同大小的行,則會導致行之間出現空白。

因此,如果你的行的內容大小完全相同,那麼你可以嘗試向你的TableViewRow添加一個className,或者移動到ListViews,它會好的。但是如果你的內容有不同的大小,那麼你必須留在TableViews上。

哦,我剛剛發現的是當TableViewRow內容很大時,內容不可見。但是如果我減小寬度,那麼內容又回來了。但是,如果這段時間內容過大,那麼它會再次消失。所以,追逐寬度是我現在得到的。希望這個信息可以幫助別人

+0

從Titanium SDK 3.2.0.GA開始,ListViews可以顯示不同大小的項目,我已經開始和那些最近開始討論,並且我喜歡它的性能。我發現了一個錯誤,導致模板中的第一級子視圖沒有固定的位置,但顯示不正確 –

相關問題