当代表具有不同的宽度时,QML ListView 滚动不会产生任何动画

Posted

技术标签:

【中文标题】当代表具有不同的宽度时,QML ListView 滚动不会产生任何动画【英文标题】:QML ListView scrolling does not produce any animation, when delegates have different width 【发布时间】:2014-12-22 17:10:58 【问题描述】:

我正在创建一个水平方向的ListView。突出显示设置为视图的一个固定位置,以便在我增加/减少当前项目时列表元素滚动通过可见区域。这是我的视图代码:

ListView 
    anchors.fill: parent
    model: ListModel
        ListElementname:"x"
        ListElementname:"y"
        ListElementname:"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

我希望当前项目的delegate 具有比所有其他元素更大的宽度。但是,当所有代表的宽度不相同时,列表滚动动画(例如,您可以看到元素移动到下一个位置,而不是仅仅出现在新位置上)不再适用。

如何让ListView 显示当前元素的宽度与其他元素的宽度不同,同时仍然能够显示滚动动画?

【问题讨论】:

【参考方案1】:

当前选中的item可以通过结合currentIndex/index属性来修改。前者是ListView 中包含的属性,用于指示所选项目(如您所知)。后者是delegate 中暴露的一个属性,用于表示列表中对应项的索引。当我们拥有它时

ListView.view.currentIndex === index

我们在当前选中的项目中。因此,在您的delegate 中,您可以这样写:

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

现在所选项目将是其他项目的两倍。不过效果有点难看。我会选择以下一个:

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

这里你说的是“当这个项目被选中时,它应该增长 50%,否则它应该缩小 50%”。

width 的最终代码如下所示:

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
            ListElementname:"a"
            ListElementname:"b"
            ListElementname:"c"
            ListElementname:"d"
            ListElementname:"e"
            ListElementname:"f"
            ListElementname:"g"
            ListElementname:"h"
            ListElementname:"i"
            ListElementname:"j"
            ListElementname:"k"
            ListElementname:"l"
            ListElementname:"x"
            ListElementname:"y"
            ListElementname:"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
    

而且效果也没有说的那么美。我会选择scale 属性,如下所示:

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
            ListElementname:"a"
            ListElementname:"b"
            ListElementname:"c"
            ListElementname:"d"
            ListElementname:"e"
            ListElementname:"f"
            ListElementname:"g"
            ListElementname:"h"
            ListElementname:"i"
            ListElementname:"j"
            ListElementname:"k"
            ListElementname:"l"
            ListElementname:"x"
            ListElementname:"y"
            ListElementname:"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
    

请注意,它严格按照要求在列表的开头(即左侧)保持高亮显示。

【讨论】:

以上是关于当代表具有不同的宽度时,QML ListView 滚动不会产生任何动画的主要内容,如果未能解决你的问题,请参考以下文章

如何在具有两个视图的 QML 中使用包?

QML 将键盘导航与多个列表视图同步

从 C++ 更改 QML Listview 委托

QML 拖放机制可以在不移动拖动项的情况下工作吗?

QML ListView 填充不透明动画

具有“填充”过渡的 QML 中继器