QML 中的自适应 UI

Adaptable UI in QML

我正在开发一个 QML 应用程序,其中包含三个主要视图。我的代码如下所示。

SplitView{
    ListView{
        id: firstView
    }
    ListView{
        id: secondView
    }
    WebView{
        id: thirdView
    }
}

现在工作正常,但我想这样做:当我的主 window 调整到低于特定宽度 (500) 时,我想只显示一个视图,以便单击委托将显示下一个视图(有可能返回到上一个视图)。因此,例如,单击第一个视图将显示第二个视图,单击第二个视图将显示第三个视图。我想要的方法与 Windows 10 中的 Mail 应用程序非常相似。 有谁知道如何在 QML 中实现这一点?

这是我解决问题的想法。

    // When width of MainWindow is smaller than 500 stop using SplitView
property bool useSplitView: (width < 500 ? false : true)
onUseSplitViewChanged: {
    if (useSplitView) {
        firstView.anchors.fill = undefined
        secondView.anchors.fill = undefined
        thirdView.anchors.fill = undefined
        firstView.parent = splitView // splitView is id of SplitView
        secondView.parent = splitView
        thirdView.parent = splitView
    }
    else {
        firstView.parent = mainWindow.contentItem // mainWindow is id of MainWindow
        secondView.parent = mainWindow.contentItem
        thirdView.parent = mainWindow.contentItem
        secondView.visible = false
        thirdView.visible = false
        firstView.anchors.fill = firstView.parent
        secondView.anchors.fill = secondView.parent
        thirdView.anchors.fill = thirdView.parent
    }
}

useSplitView 标记更改时,您需要在视图上启用某种触摸区域并在单击时在它们之间切换。

好的,我编了一个粗略的例子,我没有刻意模块化它,所以你可以看到它是如何在单一源中工作的。另外,我不知道 windows 10 邮件应用程序是如何做到的,因为我没有它,但它仍然足够接近您的描述。

您从连续 3 个列表视图开始,它们的大小可以填满整个 UI,但是如果您将 UI 的大小减少到最小值 500,视图将增加大小几乎填满整个ui,当您点击一个视图项目时,它会将您移动到下一个视图,如果您单击显示的上一个视图,您将返回到它。

ApplicationWindow {
    title: qsTr("Hello World")
    width: 800
    height: 300
    minimumWidth: 500
    visible: true

    Item {
        id: adapt
        width: parent.width
        height: parent.height
        property int sizeUnit: width > 500 ? width / 5 : 400
        property bool isPaged: width == 500 ? true : false
        onIsPagedChanged: { if (!isPaged) { x = 0; page = 0; } }
        property int page: 0

        Behavior on x { NumberAnimation { duration: 250; easing.type: Easing.OutBack } }

        ListModel {
            id: mod
            ListElement { name: "one" }
            ListElement { name: "two" }
            ListElement { name: "three" }
            ListElement { name: "four" }
            ListElement { name: "five" }
        }

        ListView {
            id: v1
            width: adapt.sizeUnit
            height: parent.height
            model: mod
            delegate: Rectangle {
                height: 70
                width: v1.width
                color: "red"
                border.color: "black"
                Text { anchors.centerIn: parent; text: name }
                MouseArea {
                    anchors.fill: parent
                    onClicked: {
                        if (adapt.isPaged) {
                            if (adapt.page == 0) {
                                adapt.x = -(v2.x - 100)
                                adapt.page = 1
                            } else {
                                adapt.x = 0
                                adapt.page = 0
                            }
                        }
                    }
                }
            }
        }

        ListView {
            id: v2
            width: adapt.sizeUnit
            height: parent.height
            x: adapt.sizeUnit + 10
            model: mod
            delegate: Rectangle {
                height: 70
                width: v2.width
                color: "cyan"
                border.color: "black"
                Text { anchors.centerIn: parent; text: name }
                MouseArea {
                    anchors.fill: parent
                    onClicked: {
                        if (adapt.isPaged) {
                            if (adapt.page == 1) {
                                adapt.x = -(v3.x - 100)
                                adapt.page = 2
                            } else {
                                adapt.x = -(v2.x - 100)
                                adapt.page = 1
                            }
                        }
                    }
                }
            }
        }

        ListView {
            id: v3
            width: adapt.isPaged ? adapt.sizeUnit : 3 * adapt.sizeUnit - 20
            height: parent.height
            x: v2.x + v2.width + 10
            model: mod
            delegate: Rectangle {
                height: 70
                width: v3.width
                color: "yellow"
                border.color: "black"
                Text { anchors.centerIn: parent; text: name }
            }
        }
    }
}

这应该足以让您继续前进。显然,对于生产,您可以进行更优雅的布局和导航,例如为实际的 "page sliding" 和锚点使用一个函数,以上只是为了示例。