我正在使用Titanium SDK 3.1.3并将Alloy项目部署到Android。 我在一个名为UserProfile的xml文件中有一个Window,如下所示:
<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中,我添加了2行图像和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());
结束编辑1
在视图中,WorkspaceContent会添加更多视图,具体取决于是否已创建注释或图像已附加到条目。
编辑2 此外,每个Stream_Item控制器都包含一个文本控制器和一个喜欢/不喜欢的控制器,这取决于条目是否有用户提及,附件和/或是一个简单的条目,还添加了额外的控制器。
我必须明确指出,这个Stream_Item控制器及其添加的控制器在其他Windows中运行良好,但在这种特定类型的Window上它会出错。
END EDIT 2
我在Android中遇到的问题是由于某些原因,行中包含的视图上的触摸事件被阻止了,我在处理TableViews时以及在多个设备中测试后,我已经知道Android上的性能问题,除非具有触摸事件的元素已完成渲染,否则将允许用户与具有触摸事件的视图交互。这只是猜测,但我认为对我的问题有点准确。我遇到的另一个问题是表格行中包含的图像有时会在滚动或与表格的其他元素交互时消失。
我从使用ScrollView转换主要是因为向表视图添加元素的方法比在ScrollView中找到的方法更实用(即在指定位置插入行的能力以及在ScrollView中找不到的行为)。我尝试了List View,但是Alloy中的实现非常混乱,并且文档不清楚如何使用其他Alloy视图动态更改内容。
有没有办法解决这些问题?如何让图像停止消失?如何绕过此触摸块?
答案 0 :(得分:2)
我对这个(消失)问题的经历也非常糟糕。由于tableView不是Android的原生元素,因为它适用于iPhone,因此Android无法完美地处理TableView并创建这些类型的问题。我多次经历过这个问题。我建议你使用ListView而不是TableView for android。只有这样,我才能说你将能够避免这些问题。而对于触摸问题。我认为你需要直接在Elements上使用TouchEvents而不是Views。你如何使用TouchEvents for Views?
答案 1 :(得分:0)
好吧,我还有同样的问题,我已经从TableView
转到ListView
,然后再回到TableView
。 ListViews比TableViews更顺畅,我猜是因为它们针对使用模板进行了优化。但ListView是针对相同大小的内容而制作的。我正在开发一个通知应用程序,我收到了不同大小的通知,不幸的是我意识到在我更改了所有代码后,我的所有通知都会在视图中被截断。所以我不得不回到tableviews,因为它们允许不同大小的行。
提高性能的另一种方法是在创建TableViewRow
时设置className。这样,行属性被缓存并用于下一行。但同样,如果您需要具有不同大小的行,这将导致行之间出现空格。
因此,如果您的行的内容大小完全相同,那么您可以尝试将className添加到TableViewRow
,或者移动到ListViews,这样就可以了。但是,如果您的内容大小不同,那么您必须继续使用TableView。
哦,我刚才想到的是,当TableViewRow
内容很大时,内容就不可见了。但如果我减小宽度,那么内容又会回来。但是如果这次内容特别大,那么它就会再次消失。所以,追逐宽度就是我现在所拥有的。希望这些信息可以帮助他人。