android - 如何修复 Android 中使用钛合金的 TableView 中触摸事件和图像消失的问题?

标签 android tableview appcelerator titanium-mobile titanium-alloy

我正在使用 Titanium SDK 3.1.3 并将 Alloy 项目部署到 Android。 我在名为 UserProfile 的 xml 文件中有一个窗口,如下所示:

<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
}

在我的表格 View 中,我添加了 2 行图像和 20 行从网络服务获得的信息,这些行在开始时也包含图像。每次用户单击“加载更多 View ”时,都会添加 20 行,其中包含从 Web 服务获取的信息。

我添加的每一行都由不同的 View 组成,具体取决于从 Web 服务接收的内容,唯一的常量是 xml 中名为 Stream_Item 的 View ,如下所示:

<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 该 Controller 的代码如下所示: //获取传递给 Controller ​​的参数 var args = 参数[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 View 中,会添加更多 View ,具体取决于是否已发表评论或是否已将图像附加到条目。

编辑2 此外,每个 Stream_Item Controller 都包含一个文本 Controller 和一个喜欢/不喜欢 Controller ,根据条目是否有用户提及、附件和/或是一个简单条目,添加其他 Controller 。

我必须澄清,这个 Stream_Item Controller 及其添加的 Controller 在其他 Windows 中工作得很好,但在这种特定类型的 Window 上它会出现错误。

结束编辑 2

我在 Android 中遇到的问题是,行中包含的 View 上的触摸事件由于某种原因被阻止,我已经知道 Android 上处理 TableView 时的性能问题,并且在多个设备中进行测试后,除非具有触摸事件的元素已完成渲染,否则将允许用户通过触摸事件与 View 进行交互。这只是一个猜测,但我认为在某种程度上准确地解决了我的问题。我遇到的另一个问题是,在滚动或与表格的其他元素交互时,表格行中包含的图像有时会消失。

我不再使用 ScrollView,主要是因为向 TableView 添加元素的方法比 ScrollView 中的方法更实用(即能够在指定位置插入行,而 ScrollView 中没有这种行为)。我尝试了 ListView ,但 Alloy 中的实现非常困惑,并且文档不清楚如何使用其他 Alloy View 动态更改内容。

有办法解决这些问题吗?如何才能让图像不再消失?我怎样才能绕过这个触摸 block ?

最佳答案

我对这个(消失)问题也有非常糟糕的经历。由于 tableView 不像 iPhone 那样是 Android 的原生元素,因此 Android 无法完美处理 TableView 并产生此类问题。我已经多次经历过这个问题。我建议你使用 ListView 而不是 Android 的 TableView。只有这样我才能说你将能够避免这些问题。还有触摸问题。我认为您需要直接在元素上使用 TouchEvents 而不是 View 。您如何使用 View 的 TouchEvents?

关于android - 如何修复 Android 中使用钛合金的 TableView 中触摸事件和图像消失的问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21034067/

相关文章:

ios - UITableViewCell Size 在运行时没有扩展。?

swift - ScrollView 中的 TableView 中的按钮未触发

ios - 在 iOS 设备上测试定位服务

javascript - 使用 Appcelerator 将基于 web2py 的 Web 应用程序转换为 native 应用程序,容易吗?可能的?

ios - atos 为 arm64 返回相同的地址

android - 设置布局以用作 ListView 的空 View ,以防适配器在 Activity 中有零个项目

android - 在 Android 中使用 EventMotion 向上滑动图像

android - 如何为 SurfaceHolder 创建 Surface?

android - Volley POST请求android

ios - 如何制作透明的tableview?