首页 文章

如何在QtQuick / QML中创建一个动画,可变大小的手风琴组件

提问于
浏览
1

我想创建一个类似动画的手风琴式元素,可以在点击时进行扩展 . 这是它应该如何工作 .

Accordion animation

当用户单击其中一个红色矩形时,应该展开作为实际内容的绿色矩形 . 我希望这个扩展能够生动 . 对于每个红色 Headers ,绿色矩形的内容的高度可以是不同的 .

我已经能够实现点击扩展行为,但没有动画 . 这是我目前的代码 .

AccordionElement.qml

import QtQuick 2.5
import QtQuick.Layouts 1.1

ColumnLayout {
    id: rootElement

    property string title: ""
    property bool isOpen: false
    default property alias accordionContent: contentPlaceholder.data

    anchors.left: parent.left; anchors.right: parent.right

    // Header element
    Rectangle {
        id: accordionHeader
        color: "red"
        anchors.left: parent.left; anchors.right: parent.right
        height: 50
        MouseArea {
            anchors.fill: parent
            Text {
                text: rootElement.title
                anchors.centerIn: parent
            }
            cursorShape: Qt.PointingHandCursor
            onClicked: {
                rootElement.isOpen = !rootElement.isOpen
            }
        }
    }

    // This will get filled with the content
    ColumnLayout {
        id: contentPlaceholder
        visible: rootElement.isOpen
        anchors.left: parent.left; anchors.right: parent.right
    }
}

这就是从父元素中使用它的方式:

Accordion.qml

ColumnLayout {
    Layout.margins: 5

    visible: true

    AccordionElement {
        title: "Title1"
        accordionContent: Rectangle {
            anchors.left: parent.left; anchors.right: parent.right
            height: 20
            color: "green"
        }
    }
    AccordionElement {
        title: "Title2"
        accordionContent: Rectangle {
            anchors.left: parent.left; anchors.right: parent.right
            height: 50
            color: "green"
        }
    }

    AccordionElement {
        title: "Title3"
        accordionContent: Rectangle {
            anchors.left: parent.left; anchors.right: parent.right
            height: 30
            color: "green"
        }
    }

    // Vertical spacer to keep the rectangles in upper part of column
    Item {
        Layout.fillHeight: true
    }
}

这会产生以下结果(当展开所有矩形时):

Expanded

理想情况下,我希望绿色矩形从红色矩形中滚出(就像打印机中的纸一样) . 但我仍然坚持如何做到这一点 . 我已经尝试了几种使用 height 属性的方法,我得到了绿色矩形消失但白色空间仍然在红色矩形下面 .

任何帮助,将不胜感激 . 有没有我错过的方法?

1 回答

  • 1

    这是一个简单快速的例子:

    // AccItem.qml
    Column {
      default property alias item: ld.sourceComponent
      Rectangle {
        width: 200
        height: 50
        color: "red"
        MouseArea {
          anchors.fill: parent
          onClicked: info.show = !info.show
        }
      }
      Rectangle {
        id: info
        width: 200
        height: show ? ld.height : 0
        property bool show : false
        color: "green"
        clip: true
        Loader {
          id: ld
          y: info.height - height
          anchors.horizontalCenter: info.horizontalCenter
        }
        Behavior on height {
          NumberAnimation { duration: 200; easing.type: Easing.InOutQuad }
        }
      }
    }
    
    // Acc.qml
    Column {
      spacing: 5
      AccItem {
        Rectangle {
          width: 50
          height: 50
          radius: 50
          color: "blue"
          anchors.centerIn: parent
        }
      }
      AccItem {
        Rectangle {
          width: 100
          height: 100
          radius: 50
          color: "yellow"
          anchors.centerIn: parent
        }
      }
      AccItem {
        Rectangle {
          width: 75
          height: 75
          radius: 50
          color: "cyan"
          anchors.centerIn: parent
        }
      }
    }
    

    你不必要地使用锚点和布局使它过于复杂 . 它似乎没有问题要求任何这些 .

    更新:我稍微改进了实现,与最初的实现相比,内容实际上会从打印机中滑出 Headers ,而不是简单地显示,并且还删除了误报绑定循环警告的来源 .

    enter image description here

相关问题