我们知道ListView在QML应用中扮演非常重要的角色。看看我们的很多的应用都是在使用ListView。那么当我们点击ListView中的item并导航到另外一个页面呢?其实这样的方法有很多。在这篇文章中,我们来介绍其中的几种。开发者可以参照其中的设计,或自己想出更好的设计。
1)使用PageStack来完成
在我们的RssReader中的例子中,我们使用了PageStack来完成我们的导航。我们可以把我们的每个页面都做成我们的Page。当我们的页面被点击后,我们把新的Page压入栈中。在返回时,我们只需要点击返回按钮即可:
我们可以在我的例程中找到相应的代码。
2)使用一个不可见的显示在需要时显示出来
在我们的使用中,我们使用两个重叠在一起的窗口,但是每次只有一个才能显示。在默认的情况下,我们显示ListView,当点击ListView中的item后,显示详细的页面:
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中实现的:
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" } } }
代码在地址 git clone https://gitcafe.com/ubuntu/listview_visible.git
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来改变的:
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; } } }
所有的源码在: git clone https://gitcafe.com/ubuntu/listview.git