ListView滚动动画

时间:2014-11-22 14:05:42

标签: qt listview animation qml qtquick2

我想为QML ListView实现滚动动画。这是一个示例图像:
ListView scrolling animation
任何人都可以建议我实施这个吗?

谢谢。

3 个答案:

答案 0 :(得分:15)

ViewTransition提供了很多有趣的示例,说明如何为ListView等操作设置动态populate(组件创建时初始项的转换),addremove(不言自明)以及其他操作。

给定ListView为每个要设置动画的操作定义元素Transition。通过简单地组合基本动画来创建您感兴趣的(或多或少)复杂行为,可以利用The animation framework创建复合动画(另请参阅here获取实际示例)。

这里有ListView的定义(第一个链接文档提供了一些不错的图像):

ListView {

    // data model, delegate, other usual stuff here...

    // transitions for insertion/deletation of elements
    add: Transition {
        NumberAnimation { property: "opacity"; from: 0; to: 1.0; duration: 500 }
        NumberAnimation { property: "scale"; easing.type: Easing.OutBounce; from: 0; to: 1.0; duration: 750 }
    }

    addDisplaced: Transition {
        NumberAnimation { properties: "y"; duration: 600; easing.type: Easing.InBack }
    }

    remove: Transition {
        NumberAnimation { property: "scale"; from: 1.0; to: 0; duration: 200 }
        NumberAnimation { property: "opacity"; from: 1.0; to: 0; duration: 200 }
    }

    removeDisplaced: Transition {
        NumberAnimation { properties: "x,y"; duration: 500; easing.type: Easing.OutBack }
    }
}

最后,请注意,可以通过使用着色器并在委托的委托/元素上的元素和过渡上组合动画来获取某些行为。一个很好的例子是Tweet Search,其中条形项上的着色效果(请参阅[ShaderEffect][5])与Transition ListView上的简单add相结合。< / p>

修改

在示例中提供自定义滚动需要考虑ItemListView的位置。工作解决方案的关键是找到一种方法来计算视图的可见部分内的Item的当前位置,并使用该值来计算适当的转换。 ListView派生自Flickable,其具有用于此目的的若干有用属性。

但是,y的{​​{1}}属性是指Item内的整体高度。有自己的立场w.r.t.在可见区域的开头,我们可以使用contentY属性。在这种情况下,一张图片胜过千言万语:

enter image description here

ListViewy之间的差异提供了一个值,可用于计算所需的转换因子(可能与contentY的{​​{1}}相关height)。实际上,当ListView被轻弹时,这两个值及其差异会发生变化,从而改变特定ListView的转换因子。

此类转换仅涵盖问题的部分。一旦轻弹/移动结束,Item的动画必须“完成”以使所有可见的Item可用。为此,我们可以利用Binding及其item属性仅在需要时激活整理动画,即flickingdragging结束时。

鉴于所有这些(无聊的)介绍,让我们考虑第二个动画(更简单的动画)。在这里,我们可以使用scale来获得所需的效果。 when中的delegate代码如下所示:

ListView

第一个ListView { id: list model: 100 spacing: 10 delegate: Rectangle { id: itemDelegate property int listY: y - list.contentY // stores the difference between the two values width: parent.width height: 50 border.color: "lightgray" color: "red" Binding { target: itemDelegate property: "scale" value: 1 - listY / list.height / 2 // the "scale" property accepts values in the range [0, 1] when: list.moving || list.flicking || list.dragging // ...when moved around } Binding { target: itemDelegate property: "scale" value: 1 // flick finished --> scale to full size! when: !(list.moving || list.dragging) // not moving or dragging any more } Behavior on scale { NumberAnimation { duration: 100; to: 1} enabled: !(list.flicking || list.dragging) // active only when flick or dragging ends! } } } Binding的基础上定义缩放因子,而第二个将缩放设置为listY,但仅在1未移动时。最终ListView平滑过渡到完全缩放的Behavior所必需的。

第三种效果可以通过Rotation

以类似的方式获得
Item

这次我选择(任意)只使用一个ListView { anchors.fill: parent id: list spacing: 10 model: 100 delegate: Rectangle { id: itemDelegate property int listY: y - list.contentY property real angleZ: (90 * listY) / list.height // 0 - 90 degrees transform: Rotation { origin.x: width / 2; origin.y: 30; axis { x: 1; y: 0; z: 0 } angle: angleZ} //transform: Rotation { origin.x: 0; origin.y: 30; axis { x: 1; y: 1; z: 0 } angle: angleZ} <--- I like this one more! width: parent.width height: 50 border.color: "lightgray" color: "red" Binding { target: itemDelegate property: "angleZ" value: 0 when: !(list.moving || list.dragging) } Behavior on angleZ { NumberAnimation {duration: 200; to: 0} enabled: !(list.flicking || list.dragging) } } } 第一个示例可以使用相同的,即我们可以在第一个代理Binding中编写。

按照类似的方法,您还可以创建第一个动画和其他动画。对于第一个动画,我认为将scale: 1 - listY / list.height / 2Translate组合就足够了。

答案 1 :(得分:9)

经过数小时的工作,研究和@BaCaRoZzo的大力帮助(感谢@BaCaRoZzo),我终于找到了正确的解决方案。只需使用Component.onCompleted()事件处理程序来运行与每个代理关联的动画。

这是一个例子,享受!

scroll animation on QML

import QtQuick 2.3

ListView {
    anchors.fill: parent
    id: list
    model: 100
    cacheBuffer: 50

    delegate: Rectangle {
        id: itemDelegate
        Component.onCompleted: showAnim.start();
        transform: Rotation { id:rt; origin.x: width; origin.y: height; axis { x: 0.3; y: 1; z: 0 } angle: 0}//     <--- I like this one more!
        width: parent.width
        height: 50
        color: index % 2 === 0 ? "#EEE" : "#DDD"
        SequentialAnimation {
            id: showAnim
            running: false
            RotationAnimation { target: rt; from: 180; to: 0; duration: 800; easing.type: Easing.OutBack; property: "angle" }
        }
    }
}

答案 2 :(得分:-1)

PathView显示从内置QML类型(如ListModelXmlListModel)创建的模型中的数据,或者继承自QAbstractListModel的C ++中定义的自定义模型类。 视图有一个模型,用于定义要显示的数据,以及一个委托,用于定义数据的显示方式。委托是为路径上的每个项目实例化的。可以轻弹这些项目以沿着路径移动它们。