0
votes

I am creating a ListView with horizontal orientation. The highlight is set to one fixed position of the view so that the list elements scroll through the visible area when I increment/decrement the current Item. Here is my code for the view:

ListView {
    anchors.fill: parent
    model: ListModel{
        ListElement{name:"x"}
        ListElement{name:"y"}
        ListElement{name:"z"}
    }
    delegate:
        Rectangle {
        property int viewW: ListView.view.width
        property bool isCurrent: ListView.isCurrentItem
        width: ListView.isCurrent? viewW * 0.4 : viewW * 0.3
        Text {
            anchors.fill: parent
            text: name
        }
    }


    orientation: Qt.Horizontal
    highlight: Rectangle {color: "transparent"}
    preferredHighlightBegin: 0
    preferredHighlightEnd: width*0.4
    highlightRangeMode: ListView.StrictlyEnforceRange
}

I want the delegate of the current item to have a greater width than all the other elements. However, when the width of all delegates is not identical, the list scrolling animation (e.g. you can see elements moving to next position, instead of just appearing on the new position) does not apply any more.

How can I have a ListView with the current element showing a different width than the rest of the other elements, while still being able to have the scrolling animations?

1

1 Answers

0
votes

The currently selected item can be modified by combining the property to modify with the currentIndex/index properties. The former is the property contained in the ListView to indicate the selected item (as you already know). The latter is a property exposed in the delegate to represent the index of the corresponding item in the list. When we have that

ListView.view.currentIndex === index

we are in the currently selected item. Hence, in your delegate, you can write something like this:

width: ListView.view.currentIndex === index ? 60 : 30 

Now the selected item will be twice as large as the other items. However the effect is a little bit ugly. I would go for the following one:

scale: ListView.view.currentIndex === index ? 1.5 : 0.5

Here you are saying that "when this item is the selected one it should grow by 50%, otherwise it should shrink by 50%".

The final code for the width could look like this:

import QtQuick 2.3
import QtQuick.Window 2.0
import QtQuick.Controls 1.2

Window {
    id: container
    width: 300
    height: 150
    visible: true

    ListView {
        id: list
        anchors.fill: parent
        spacing: 5

        model: ListModel{
            ListElement{name:"a"}
            ListElement{name:"b"}
            ListElement{name:"c"}
            ListElement{name:"d"}
            ListElement{name:"e"}
            ListElement{name:"f"}
            ListElement{name:"g"}
            ListElement{name:"h"}
            ListElement{name:"i"}
            ListElement{name:"j"}
            ListElement{name:"k"}
            ListElement{name:"l"}
            ListElement{name:"x"}
            ListElement{name:"y"}
            ListElement{name:"z"}
        }

        delegate:
            Rectangle {
            width: ListView.view.currentIndex === index ? 60 : 30  // the magnifying/shrinking
            color: "steelblue"

            height: ListView.view.height
            Text {
                anchors.centerIn: parent
                text: name
                font.pixelSize: 20
            }

            Behavior on width {                    // added to smooth the resizing
                NumberAnimation { duration: 100 }
            }
        }

        orientation: Qt.Horizontal
        highlight: Rectangle {color: "transparent"}
        preferredHighlightBegin: 0
        preferredHighlightEnd: delegate.width
        highlightRangeMode: ListView.StrictlyEnforceRange
    }
}

And the effect is not that beautiful as said. I would go for the scale property, as follows:

import QtQuick 2.3
import QtQuick.Window 2.0
import QtQuick.Controls 1.2

Window {
    id: container
    width: 300
    height: 150
    visible: true

    ListView {
        id: list
        anchors.fill: parent
        spacing: 5

        model: ListModel{
            ListElement{name:"a"}
            ListElement{name:"b"}
            ListElement{name:"c"}
            ListElement{name:"d"}
            ListElement{name:"e"}
            ListElement{name:"f"}
            ListElement{name:"g"}
            ListElement{name:"h"}
            ListElement{name:"i"}
            ListElement{name:"j"}
            ListElement{name:"k"}
            ListElement{name:"l"}
            ListElement{name:"x"}
            ListElement{name:"y"}
            ListElement{name:"z"}
        }

        delegate:
            Rectangle {
            scale: ListView.view.currentIndex === index ? 1.5 : 0.5
            color: "transparent"
            width: 30
            height: ListView.view.height
            Text {
                anchors.centerIn: parent
                text: name
                font.pixelSize: 20
            }

            Behavior on scale {                    // added to smooth the scaling
                NumberAnimation { duration: 100 }
            }
        }

        orientation: Qt.Horizontal
        highlight: Rectangle {color: "steelblue"}
        preferredHighlightBegin: 0
        preferredHighlightEnd: delegate.width
        highlightRangeMode: ListView.StrictlyEnforceRange
    }
}

Note that the highlight it strictly maintained at the beginning of the list (i.e. at the left side) as required.