0

In my qml application there is content area "Item" and it have a "loader" for load qml file.

I want to implement leave and enter animation effect

For example my current source of loader is "First.qml" when i set source other qml file(second.qml). "First.qml" should fade out and "second.qml" will be fade in.

How should i achieve this?

I tried following code it animate only the second.qml. When we set source "first.qml" disappears. I want to give a fadeout animation to intial qml also ("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")


                    }


                }
hareesh
  • 37
  • 7

2 Answers2

1

Ok, so the way i see it is you have two main options..

1) Use a SequentialAnimation that fades out the first view, loads in the second then fades it in with something like..

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
    }
}

This method would result in the area being blank for a fraction of a second. Whereas as second option would be..

2) Cross-fade by adding in a second Loader and then when you select the button you cross-fade on opacity. This could look something like..

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()
    }
}

There may be errors in this as not in a position to run the code right now!

teh_raab
  • 384
  • 1
  • 3
  • 21
1

An alternative would be to use StackView, since it has support for custom animations.

Using it's replace function, you could change the item being shown.

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
            }
        }
    }
}
GrecKo
  • 6,615
  • 19
  • 23