1

我想在ListView捕捉到特定项目时为“捕捉”效果设置动画。

我启用了snapMode: ListView.SnapOneItem属性的“捕捉”。目前它只是减速到当前项目并停止,但如果我能让它在停止时产生“反弹”效果,那就太好了。

关于我如何做到这一点的任何想法?

Flickable有一个rebound属性,但这似乎不适用于在ListView.

4

1 回答 1

1

由于您使用SnapOneItem,您可以在移动完成后插入反弹效果,即一旦movementEnded发出信号。在这种情况下,IMO 对每个项目应用动画将是矫枉过正。更好的做法是contentYListView.

以下是产生反弹的可能方法(不知道这是否是您正在搜索的确切效果):

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)。periodto

编辑

如您所见,如果列表通过incrementCurrentIndex()没有实际移动发生移动,即movementEnded不会发出信号。在这种情况下,您可以利用currentIndex. 我已经修改了示例,将这种方法与前一种方法结合起来,并展示了我插入Timer调用incrementCurrentIndex()函数的用法。

添加检查是为了避免在!list.moving移动列表时出现双重动画并保证示例中的一致性,因为在Timer拖动列表时会产生不一致的跳转。显然,可以根据您的要求添加其他更具体的约束。

于 2014-11-28T12:56:32.247 回答