QML中的进入和离开动画

Enter and Leave animation in QML

在我的 qml 应用程序中有内容区域 "Item" 并且它有一个 "loader" 用于加载 qml 文件。

我想实现进出动画效果

例如,当我将源设置为其他 qml 文件时(second.qml),我当前的加载器源是 "First.qml"。 "First.qml" 应该淡出,"second.qml" 会淡入。

我该如何实现?

我尝试了以下代码,它只为 second.qml 设置动画。当我们设置源时 "first.qml" 消失。我也想给初始 qml 一个淡出动画 ("first.qml")

 Loader{
            id:contentLoader
            source: "First.qml"

            onSourceChanged: animation.running = true

                    NumberAnimation {
                        id: animation
                        target: contentLoader.item
                        property: "opacity"
                        from: 0
                        to: 1
                        duration: 1000
                        easing.type: Easing.bezierCurve
                    }

        }
//button click
 Button{
                    text:modelData
                    width:100
                    height: parent.height

                    onClicked: {

                         contentLoader.setSource("Second.qml")


                    }


                }

好的,所以我认为您有两个主要选择..

1) 使用 SequentialAnimation 淡出第一个视图,加载第二个视图,然后用类似...

的方式淡入
SequentialAnimation {
    id: switchContentAnimation

    //Fade out first view
    NumberAnimation {
        target: contentLoader
        property: "opacity"
        duration: 1000
        from: 0
        to: 1
    }

    //Switch view
    ScriptAction { script: contentLoader.setSource("Second.qml"); }

    //Fade new view back in
    NumberAnimation {
        target: contentLoader
        property: "opacity"
        duration: 1000
        from: 0
        to: 1
    }
}

此方法会导致该区域在几分之一秒内为空白。而第二种选择是..

2) 通过添加第二个 Loader 来交叉淡入淡出,然后当您 select 按钮时,您会在不透明度上交叉淡入淡出。这可能看起来像..

property bool activeView: false //false: first, true: second
Loader{
    id:contentLoaderOne
    source: "First.qml"
    onOpacityChanged: {
        if(opacity == 0) {
            //unload this loaders source to save memory
        }
    }
}
Loader{
    id:contentLoaderTwo
    onOpacityChanged: {
        if(opacity == 0) {
            //unload this loaders source to save memory
        }
    }
}
ParallelAnimation {
    id: switchContentAnimation
    NumberAnimation {
        target: contentLoaderOne
        properties: "opacity"
        duration: 1000
        to: (activeView) ? 1 : 0
    }
        NumberAnimation {
        target: contentLoaderTwo
        properties: "opacity"
        duration: 1000
        to: (!activeView) ? 1 : 0
    }
}

//button click
Button{
    text:modelData
    width:100
    height: parent.height
    onClicked: {
        if(activeView) {
            //switch to second view..
            contentLoaderTwo.setSource("Second.qml")
        }
        else {
            //switch back to first view..
            contentLoaderOne.setSource("First.qml")
        }
        activeView = !activeView;
        switchContentAnimation.start()
    }
}

这里可能有错误,因为现在无法 运行 代码!

另一种方法是使用 StackView,因为它支持自定义动画。

使用它的 replace 功能,您可以更改显示的项目。

import QtQuick 2.9
import QtQuick.Controls 2.2

ApplicationWindow {
    id : root
    title: qsTr("Hello World")
    width: 640
    height: 480
    visible:true

    Component {
        id: lightblueRectangleComponent
        Rectangle {
            color: "lightblue"
            Button {
                anchors.centerIn: parent
                text: "replace"
                onClicked: stackView.replace(orangeRectangleComponent)
            }
        }
    }

    Component {
        id: orangeRectangleComponent
        Rectangle {
            color: "orange"
            Button {
                anchors.centerIn: parent
                text: "replace"
                onClicked: stackView.replace(lightblueRectangleComponent)
            }
        }
    }

    StackView {
        id: stackView
        anchors.fill: parent
        initialItem: lightblueRectangleComponent

        replaceEnter: Transition {
            PropertyAnimation {
                property: "opacity"
                from: 0
                to:1
                duration: 200
                easing.type: Easing.OutQuad
            }
        }
        replaceExit: Transition {
            PropertyAnimation {
                property: "opacity"
                from: 1
                to:0
                duration: 200
                easing.type: Easing.InQuad
            }
        }
    }
}