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" 和锚点使用一个函数,以上只是为了示例。
我正在开发一个 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" 和锚点使用一个函数,以上只是为了示例。