首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >交错(砌体) GridView或Flow

交错(砌体) GridView或Flow
EN

Stack Overflow用户
提问于 2021-08-18 12:59:53
回答 1查看 262关注 0票数 1

我在以下问题中遇到了同样的问题:

How does one create a staggered grid view in QML?

我希望在砖石风格中实现Flow GridLayoutGridView,请参阅当前输出的附加图片和所需的图片。

目前:

所需:

我不想为此使用外部库,而只是使用QML和JavaScript。

我已经尝试过一些东西,比如在一个可以闪烁的地方流动:

代码语言:javascript
运行
复制
Flickable
{
    anchors.fill: parent
    anchors.margins: 5
    contentHeight: flow.height

    Flow {
        id: flow
        width: parent.width
        height: 800
        spacing: 10
        flow: Flow.TopToBottom
        Repeater{
            model: [80,60,120,75,90,55,140,50,70,90,80,60,120,75,90]
            Rectangle {
                height: modelData
                width: 100
                border.color: "black"
            }
        }
    }
}

我的GridLayout也在使用preferredHeightfillHeight

代码语言:javascript
运行
复制
Layout.fillWidth: true
Layout.fillHeight: true
Layout.preferredWidth: Layout.columnSpan
Layout.preferredHeight: Layout.rowSpan

但是,两者都存在将rowHeight设置为每行最高对象的问题。

我的问题是

如何在网格中创建不相等的单元格大小,其中行没有锁定到砖石视图的最高对象?

现在出现的唯一的“麻烦”解决方案是有两个列表,一个模型是每个奇数索引,另一个是附加在同一个闪烁对象上的偶数索引,因此它们作为一个对象滚动,但是肯定有更好的方法来实现没有空格的砖石视图吗?我对此进行了测试,它确实有效;(见下文)但是,是否有更好的方法来实现?

代码语言:javascript
运行
复制
    function isEven(n) {
        return n % 2 == 0;
    }

    function isOdd(n) {
        return Math.abs(n % 2) == 1;
    }

    JsonListModel {
        id: jsonModel; source: userFeed; keyField: "id"
        fields: ["id", "owner", "downloadUrl","profile_Pic_URL", "tag", "timestamp","post_description", "team", "liked_by", "location"]
    }
    SortFilterProxyModel {
        id: sortedModelOdd;
        Component.onCompleted: {app.userFeedChanged();sourceModel = jsonModel}
        filters: [
            ExpressionFilter {expression: model.tag === exploreFilter},
            ExpressionFilter {expression: isOdd(index)}
        ]
        sorters: RoleSorter {roleName: "timestamp"; ascendingOrder: false}
    }
    SortFilterProxyModel {
        id: sortedModelEven;
        Component.onCompleted: {app.userFeedChanged();sourceModel = jsonModel}
        filters: [
            ExpressionFilter {expression: model.tag === exploreFilter},
            ExpressionFilter {expression: isEven(index)}
        ]
        sorters: RoleSorter {roleName: "timestamp"; ascendingOrder: false}
    }

// i create 2 versions of the same model by using my expressionFilter for odds/evens

    ScrollView {
        anchors.fill: parent
        Row {
            anchors.fill: parent
            spacing: dp(5)
            anchors.margins: dp(5)
            AppListView {
                id: evenModelView
                model: sortedModelEven; emptyText.text: qsTr("No posts yet!"); scale: 0.96
                width: parent.width/2; spacing: dp(5); scrollIndicatorVisible: false;
                delegate: AppImage {width: parent.width; fillMode: Image.PreserveAspectFit; source: model.downloadUrl}
            }
            AppListView {
                id: oddModelView
                model: sortedModelOdd; emptyText.text: qsTr("No posts yet!"); scale: 0.96
                width: parent.width/2; spacing: dp(5);scrollIndicatorVisible: false;
                delegate: AppImage {width: parent.width; fillMode: Image.PreserveAspectFit; source: model.downloadUrl}
            }
        }
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-08-19 13:58:01

我已经找到了一个解决方案(我在我的问题中谈到了这个问题--并对其进行了改进),所以我会将其作为答案发布,但仍然很高兴听到是否有人使用实际布局实现了这个结果。

代码语言:javascript
运行
复制
    JsonListModel {
        id: jsonModel; source: jsonArray; keyField: "id"
        fields: ["id", "owner", "downloadUrl","profile_Pic_URL", "tag", "timestamp","post_description", "team", "liked_by", "location"]
    }
    SortFilterProxyModel {
        id: sortedModelOdd; Component.onCompleted: {sourceModel = jsonModel}
        filters: [ExpressionFilter {expression: model.tag === exploreFilter; enabled: exploreFilter !== "Everything"}, ExpressionFilter {expression: isOdd(index)}]
        sorters: RoleSorter {roleName: "timestamp"; ascendingOrder: false}
    }
    SortFilterProxyModel {
        id: sortedModelEven; Component.onCompleted: {sourceModel = jsonModel}
        filters: [ExpressionFilter {expression: model.tag === exploreFilter; enabled: exploreFilter !== "Everything"}, ExpressionFilter {expression: isEven(index)}]
        sorters: RoleSorter {roleName: "timestamp"; ascendingOrder: false}
    }


    AppFlickable {
        id: flickable
        anchors.fill: parent; contentHeight: scrollRow.height + dp(Theme.navigationBar.height)*2; anchors.topMargin: scrollModel.height
        Row {
            id: scrollRow; width: parent.width
            Column {
                id: col; spacing: dp(5); width: parent.width/2
                Behavior on y {
                    NumberAnimation {properties: "y"; duration: 1000 }
                }
                Repeater {

                    id: evenModelView; model: sortedModelEven;
                    delegate: AppCard {
                        id: evenImage; width: (parent.width)-dp(2); margin: dp(5); paper.radius: dp(5); scale: 0.96;
                        media: AppImage {
                            width: parent.width; fillMode: Image.PreserveAspectFit; source: model.downloadUrl; autoTransform: true
                            MouseArea {anchors.fill: parent; onPressAndHold: PictureViewer.show(homePage, model.downloadUrl); onReleased: PictureViewer.close(); onClicked: {exploreStack.push(viewPostComp, {postID: model.id})}}
                        }
                        content: AppText {
                            width: parent.width; padding: dp(15); maximumLineCount: 2; elide: Text.ElideRight; wrapMode: Text.Wrap; text: model.owner.username
                            MouseArea {anchors.fill: parent; onClicked: exploreStack.push(otherUserComp, {userID: model.owner.id})}
                        }
                        actions: Row {
                            IconButton {
                                icon: {
                                    var likedList = Object.keys(model.liked_by.list)
                                    likedList.indexOf(userData.id) ? IconType.heart : IconType.hearto}
                                onClicked: {likedList.indexOf(userData.id) ? dataModel.likePost(model.id, false, model.liked_by.count, model.owner.id) : dataModel.likePost(model.id, true, model.liked_by.count, model.owner.id)}
                            }
                        }
                    }
                }
            }
            Column {
                id: oddCol; spacing: dp(5); width: parent.width/2
                Repeater {
                    id: oddModelView; model: sortedModelOdd;
                    delegate: AppCard {
                        id: oddImage; width: (parent.width)-dp(2); margin: dp(5); paper.radius: dp(5); scale: 0.96;
                        media: AppImage {
                            width: parent.width; fillMode: Image.PreserveAspectFit; source: model.downloadUrl; autoTransform: true
                            MouseArea {anchors.fill: parent; onPressAndHold:  PictureViewer.show(homePage, model.downloadUrl); onReleased: PictureViewer.close(); onClicked: {exploreStack.push(viewPostComp, {postID: model.id})}}
                        }
                        content: AppText{
                            width: parent.width; padding: dp(15); maximumLineCount: 2; elide: Text.ElideRight; wrapMode: Text.Wrap; text: model.owner.username;
                            MouseArea {anchors.fill: parent; onClicked: exploreStack.push(otherUserComp, {userID: model.owner.id})}
                        }
                        actions: Row {
                            IconButton {
                                icon: {
                                    var likedList = Object.keys(model.liked_by.list)
                                    likedList.indexOf(userData.id) ? IconType.heart : IconType.hearto}
                                onClicked: {likedList.indexOf(userData.id) ? dataModel.likePost(model.id, false, model.liked_by.count, model.owner.id) : dataModel.likePost(model.id, true, model.liked_by.count, model.owner.id)}
                            }
                        }
                    }
                }
            }
        }
    }

备注:

我最初使用的是ScrollView而不是Flickable,但是这造成了严重的性能问题。

我把它放在一个Loader中,它在某种程度上解决了这个问题,因为它在运行时并没有影响性能,然后我改为了一个Flickable,到目前为止它已经导致了0个问题(还没有用一个大型模型进行测试)。

每个AppListView都需要禁用交互功能,否则有时滚动只会捕捉到其中一个列,并使它们不同步。

(见实施结果图)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68832902

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档