Search code examples
listviewqmlqtquick2pull-to-refreshubuntu-touch

ListView PullToRefresh hide "Pull to refresh" string under a row above


I'm creating a QML layout with a Column and multiple Rows inside. First row contains a button, second row contains a list of items retrieved from a network service. I want to be able to do "pull to refresh" on the list, so I use PullToRefresh of the ListView.

However, this adds the visible string "Pull to refresh..." to the top of the row output, actually appearing near the top of the first row. This kind of makes sense, except that I want that text to be hidden under the first row until it slides out when the list in the 2nd row is pulled.

Here's the minimum QML to reproduce, which can be run with qmlscene:

import QtQuick 2.4
import QtQuick.XmlListModel 2.0
import Ubuntu.Components 1.3

MainView {

    id: root
    width: units.gu(50)
    height: units.gu(75)

    Column {
        Row {
            Button {
                id: selector
                text: "Select"
            }
        }
        Row {
            ListView {
                id: listOfThings
                height: 500
                width: 400
                model: things
                delegate: Text {
                    text: title + " (" + pubDate + ")"
                }
                PullToRefresh {
                    refreshing: things.status === XmlListModel.Loading
                    onRefresh: things.reload()
                }
            }
        }
    }

    XmlListModel {
        id: things
        source: "https://news.yahoo.com/rss/"
        query: "/rss/channel/item"
        XmlRole { name: "title"; query: "title/string()" }
        XmlRole { name: "pubDate"; query: "pubDate/string()" }
    }
}

I cannot get the "Pull to refresh..." string to hide under the first row. Things I've tried so far that didn't work:

  • set z values, higher value for first row, lower for the 2nd: no effect
  • enclosing the button in the first row inside a Rectangle: the rectangle doesn't auto-stretch to fit the button and row dimensions collapse to 0
  • placing a white Rectangle in the first row, to the right of the button: this has been the most promising, but it's quite a hack
  • setting a background of a row: didn't find how that was possible

This must be a common use case, but I can't find any answers/examples. How do I hide the "Pull to refresh..." string under the row above it, until it is pulled into the row below? Or, are Column and Rows not the right components to use when doing this?


Solution

  • Try adding this line:

            ListView {
                id: listOfThings
                clip: true   // <- this line! 
                height: 500
                width: 400