qtlistviewqmlswipeviewqtquickcontrols2

QML: Mid-swipe position of item in SwipeView


I'm trying to create a Parallax View based on a SwipeView element. Examples in QML documentation illustrate how to achieve it with ListView:

Image {
    id: background
    source: "background.png"
    fillMode: Image.TileHorizontally
    x: -list.contentX / 2
    width: Math.max(list.contentWidth, parent.width)
}

ListView {
    id: list
    anchors.fill: parent
    spacing: 20
    snapMode: ListView.SnapToItem
    orientation: ListView.Horizontal
    highlightRangeMode: ListView.StrictlyEnforceRange
    boundsBehavior: Flickable.StopAtBounds
    maximumFlickVelocity: 1000

    model: _some_cpp_list
    //Loader is used as a workaround for QTBUG-49224
    delegate: Loader {
        id: loaderDelegate
        source: "MyDelegate.qml"
        width: myScreen.width
        height: myScreen.height
        onLoaded: {
            loaderDelegate.item.logic = modelData
        }
    }
}

Now, this works, but instad of ListView I want to use SwipeView, since it requires less code to achieve the behaviour I want:

SwipeView {
    id: list
    anchors.fill: parent
    spacing: 20
    Repeater {
        model: _some_cpp_list
        delegate: MyDelegate {
            logic: modelData
        }
    }

Is there any way I could access SwipeView's current "x" position or swipe offset to use in this line:

x: -list.contentX / 2?

The closest I've found so far is x: -swipeView.contentData[0].x / 2, but it causes jumping over items rather than smooth transition.


Solution

  • You can't control the x-coordinate of items in a horizontal ListView, because the item positions are managed by the ListView. The reason why you're able to manipulate the item positions in your first example is that you're not actually manipulating the delegate position, but another item wrapped into a Loader delegate.

    For SwipeView pages, unless you want to use similar wrappers, you could apply a transformation using the Translate QML type. You can access SwipeView's internal ListView and its contentX via SwipeView.contentItem. Calculating the desired parallax effect is left as an exercise for the reader. :)

    PS. See also the ParallaxView example at https://doc.qt.io/qt-5/qtquick-views-example.html.