我们知道ListView在QML应用中扮演非常重要的角色。看看我们的很多的应用都是在使用ListView。那么当我们点击ListView中的item并导航到另外一个页面呢?其实这样的方法有很多。在这篇文章中,我们来介绍其中的几种。开发者可以参照其中的设计,或自己想出更好的设计。
1)使用PageStack来完成
在我们的
RssReader中的例子中,我们使用了PageStack来完成我们的导航。我们可以把我们的每个页面都做成我们的Page。当我们的页面被点击后,我们把新的Page压入栈中。在返回时,我们只需要点击返回按钮即可:
我们可以在我的例程中找到相应的代码。
2)使用一个不可见的显示在需要时显示出来
在我们的使用中,我们使用两个重叠在一起的窗口,但是详细的页面只有在ListView中的item被点击后才能显示。在默认的情况下,我们显示ListView。
ListView {
id: listview
clip: true
anchors.fill: parent
model:mymodel
header: Text {
text: "This is the header"
font.pixelSize: 30
Rectangle {
anchors.top: parent.bottom
width: listview.width
height: units.gu(0.4)
color: "blue"
}
}
delegate: MyDelegate {}
footer: Text {
text: "This is the footer"
font.pixelSize: 30
}
}
Item {
id: popup
visible: false
clip: true
property url loadUrl
onLoadUrlChanged: {
opacity = 0;
visible = (loadUrl == '' ? false : true);
console.log("opacity: " + opacity );
console.log("visible: " + visible );
}
anchors.fill: parent
Rectangle {
id: bg
anchors.fill: parent
color: "white"
}
MouseArea{
anchors.fill: parent
enabled: popup.visible
//Eats mouse events
}
Loader{
focus: true
source: popup.loadUrl
width: parent.width
height: parent.height -toolbar.height
}
Rectangle {
id: toolbar
width: parent.width
height: units.gu(4)
anchors.bottom: parent.bottom
color: "blue"
Icon {
name: "previous"
width: units.gu(3.5)
height: units.gu(3.5)
MouseArea {
anchors.fill: parent
onClicked: {
popup.loadUrl = "";
ani.running = true;
}
}
}
}
NumberAnimation on opacity {
id: ani
from: 0
to: 1
duration: 3000
}
}
}
在上面的代码中,默认的情况下,我们试popup为不可见,它和listview是重叠在一起的。当item被点击后,我们才修改它为可见。这个代码在MyDelegate中实现的:
MyDelegate.qml
import QtQuick 2.0
Item {
property Item item
width: listview.width
height: units.gu(8)
Text {
id: text
text: title
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: units.gu(10)
font.pixelSize: 30
}
Rectangle {
anchors.top: text.bottom
width: parent.width
height: units.gu(0.2)
color: "gray"
}
Image {
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
source: "images/arrow.png"
rotation: -90
}
MouseArea {
anchors.fill: parent
onClicked: {
console.log("it is clicked");
popup.loadUrl = "ExampleQml.qml"
}
}
}
代码在地址 https://github.com/liu-xiao-guo/listview_visible
3)使用一个左右结构的页面,每次只有一个页面显示
同样的方法,我们可以使用一个左右排列的两个页面。每个页面的大小和主屏是一样大小的。但是,只有一个页面在不同的时间显示。我们可以通javascript来控制什么时候显示哪个页面。我们可以通过改变x坐标来显示我们所需要的页面。可以结合动画来展示效果:
Row {
id: view
ListView {
id: listview
clip: true
width: root.width
height: root.height
model:mymodel
header: Text {
text: "This is the header"
font.pixelSize: 30
Rectangle {
anchors.top: parent.bottom
width: listview.width
height: units.gu(0.4)
color: "blue"
}
}
delegate: MyDelegate {}
footer: Text {
text: "This is the footer"
font.pixelSize: 30
}
}
// This is the second page
DetailedPage {
id: detailPage
width: root.width
height: root.height
}
Behavior on x {
NumberAnimation { duration: 500 }
}
}
通过使用Row来把两个页面并列显示,但是,每次只显示其中的一个页面。当点击ListView中的item后,改变当前view的x坐标来显示另外一个页面。这个是通过MyDelegate来改变的:
MyDelegate.qml
import QtQuick 2.0
Item {
property Item item
width: listview.width
height: units.gu(8)
Text {
id: text
text: title
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: units.gu(10)
font.pixelSize: 30
}
Rectangle {
anchors.top: text.bottom
width: parent.width
height: units.gu(0.2)
color: "gray"
}
Image {
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
source: "images/arrow.png"
rotation: -90
}
MouseArea {
anchors.fill: parent
onClicked: {
// popup.loadUrl = "ExampleQml.qml"
view.x = -root.width;
}
}
}
当然我们也可以把画面弄成上下排列的,使用同样的方法,我们可以把详细的画面移动到我们的视口中即可。