diff --git a/examples/gallery/contents/ui/gallery/ListViewGallery.qml b/examples/gallery/contents/ui/gallery/ListViewGallery.qml --- a/examples/gallery/contents/ui/gallery/ListViewGallery.qml +++ b/examples/gallery/contents/ui/gallery/ListViewGallery.qml @@ -39,14 +39,24 @@ background: Rectangle { color: Theme.viewBackgroundColor } + pageHeader: Component { + Controls.Button { + text: "Important information on top" + onClicked: theList.positionViewAtBeginning() + } + } ListView { + id: theList Timer { id: refreshRequestTimer interval: 3000 onTriggered: page.refreshing = false } model: 200 + header: Label { + text: "super important information" + } delegate: BasicListItem { label: "Item " + modelData } diff --git a/src/controls/ScrollablePage.qml b/src/controls/ScrollablePage.qml --- a/src/controls/ScrollablePage.qml +++ b/src/controls/ScrollablePage.qml @@ -115,6 +115,13 @@ */ property alias bottomPadding: scrollView.bottomPadding + /** + * pageHeader: Component + * Places an item on top of the view when the user scrolls, so that we can + * have some UI available at all time. + */ + property alias pageHeader: pageHeaderLoader.sourceComponent + children: [ RefreshableScrollView { id: scrollView @@ -131,6 +138,34 @@ id: overlay anchors.fill: parent property Item oldContentItem + + Loader { + id: pageHeaderLoader + anchors { + left: parent.left + right: parent.right + } + + Behavior on y { + NumberAnimation { + duration: Units.longDuration + easing.type: Easing.InOutQuad + } + } + + states: [ + State { + name: "top" + when: root.flickable.contentY > 0 + PropertyChanges { target: pageHeaderLoader; y: 0 } + }, + State { + name: "scrolled" + when: root.flickable.contentY <= 0 + PropertyChanges { target: pageHeaderLoader; y: -height } + } + ] + } } ]