我想为QML ListView
实现滚动动画。这是一个示例图像:
任何人都可以建议我实施这个吗?
谢谢。
答案 0 :(得分:15)
ViewTransition提供了很多有趣的示例,说明如何为ListView
等操作设置动态populate
(组件创建时初始项的转换),add
,remove
(不言自明)以及其他操作。
给定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>
在示例中提供自定义滚动需要考虑Item
内ListView
的位置。工作解决方案的关键是找到一种方法来计算视图的可见部分内的Item
的当前位置,并使用该值来计算适当的转换。 ListView
派生自Flickable
,其具有用于此目的的若干有用属性。
但是,y
的{{1}}属性是指Item
内的整体高度。有自己的立场w.r.t.在可见区域的开头,我们可以使用contentY
属性。在这种情况下,一张图片胜过千言万语:
ListView
和y
之间的差异提供了一个值,可用于计算所需的转换因子(可能与contentY
的{{1}}相关height
)。实际上,当ListView
被轻弹时,这两个值及其差异会发生变化,从而改变特定ListView
的转换因子。
此类转换仅涵盖问题的部分。一旦轻弹/移动结束,Item
的动画必须“完成”以使所有可见的Item
可用。为此,我们可以利用Binding
及其item
属性仅在需要时激活整理动画,即flicking
或dragging
结束时。
鉴于所有这些(无聊的)介绍,让我们考虑第二个动画(更简单的动画)。在这里,我们可以使用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 / 2
与Translate
组合就足够了。
答案 1 :(得分:9)
经过数小时的工作,研究和@BaCaRoZzo的大力帮助(感谢@BaCaRoZzo),我终于找到了正确的解决方案。只需使用Component.onCompleted()
事件处理程序来运行与每个代理关联的动画。
这是一个例子,享受!
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类型(如ListModel
和XmlListModel
)创建的模型中的数据,或者继承自QAbstractListModel
的C ++中定义的自定义模型类。
视图有一个模型,用于定义要显示的数据,以及一个委托,用于定义数据的显示方式。委托是为路径上的每个项目实例化的。可以轻弹这些项目以沿着路径移动它们。