【问题标题】:Animate snap in ListViewListView 中的动画捕捉
【发布时间】:2014-11-28 10:15:42
【问题描述】:
我想在ListView 捕捉到特定项目时为“捕捉”效果设置动画。
我使用snapMode: ListView.SnapOneItem 属性启用“捕捉”。目前它只是减速到当前项目并停止,但如果我能让它在停止时产生“反弹”效果,那就太好了。
关于如何做到这一点的任何想法?
Flickable 有一个rebound 属性,但这似乎不适用于捕捉ListView 内的元素。
【问题讨论】:
标签:
qt
listview
qml
qtquick2
qt5.3
【解决方案1】:
由于您使用了SnapOneItem,因此您可以在移动完成后插入反弹效果,即一旦发出movementEnded 信号。在这种情况下,IMO 对每个项目应用动画将是矫枉过正。最好为ListView 的contentY 属性设置动画。
以下是产生反弹的可能方法(不知道这是否是您正在搜索的确切效果):
ListView {
id: list
anchors.fill: parent
spacing: 10
snapMode: ListView.SnapOneItem
model: 100
delegate: Rectangle {
width: parent.width
height: 50
Text { // added text to distinguish items
text: index
font.pixelSize: 20
anchors.centerIn: parent
}
color: index % 2 ? "lightGray" : "darkGrey"
}
onMovementEnded: {
bounce.start() // starts the animation when the movement ends
}
onCurrentIndexChanged: {
if(!list.moving) // animation started only if the list is not moving
bounce.start()
}
Timer {
repeat: true
interval: 2000 // enough time to let the animation play
running: true
onTriggered: {
list.incrementCurrentIndex()
}
}
SequentialAnimation {
id: bounce
running: false
NumberAnimation {
target: list
property: "contentY"
to: list.contentY - 10
easing {
type: Easing.InOutBack
amplitude: 2.0
period: 0.5
}
duration: 250
}
NumberAnimation {
target: list
property: "contentY"
to: list.contentY
duration: 800
easing {
type: Easing.OutBounce
amplitude: 3.0
period: 0.7
}
}
}
}
当您从拖动或移动中释放项目时,会产生弹跳。可以调整amplitude 和period 属性以获得更强或更轻的效果(同样适用于to 属性的值)。
编辑
如您所见,如果列表通过incrementCurrentIndex() 移动,则不会发生真正的移动,即不会发出movementEnded 信号。在这种情况下,您可以利用 currentIndex 发生的值变化。我修改了这个例子,将这种方法与前一种方法结合起来,并展示了我插入Timer 来调用incrementCurrentIndex() 函数的用法。
添加!list.moving检查是为了避免列表移动时出现双重动画并保证示例中的一致性,因为Timer会在列表被拖动时产生不一致的跳转。显然,可以根据您的要求添加其他更具体的约束。