如何在 QtQuick/QML 中创建动画、可变大小的手风琴组件 [英] How to create an animated, variable size accordion component in QtQuick / QML

查看:23
本文介绍了如何在 QtQuick/QML 中创建动画、可变大小的手风琴组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to create an animated accordion-like element that expands on click. Here's how it should work.

当用户点击红色矩形之一时,作为实际内容的绿色矩形应该展开.我希望这个扩展是动画的.每个红色标题的绿色矩形内容的高度可能不同.

When the user clicks one of the red rectangles, the green rectangle which is the actual content, should expand. I want this expansion to be animated. The height of the contents of the green rectangles could be different for each red header.

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

I have been able to implement the click-to-expand behavior, but there's no animation. Here is the code I currently have.

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

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

And this is how it is used from the parent element:

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

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

This produces the following result (when all rectangles are expanded):

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

Ideally I would like the green rectangles to roll out of the red rectangles (like paper out of a printer). But I am stuck on how to do this. I have tried several approaches using the height property, and I got the green rectangle to disappear but the white space remains under the red rectangle.

任何帮助将不胜感激.有没有我缺少的方法?

Any help would be appreciated. Is there an approach I'm missing?

推荐答案

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

Here is a quick and simple example:

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

您不必要地将锚点和布局过度复杂化.似乎这些问题都不是问题.

You are needlessly over-complicating it with the anchors and the layouts. It doesn't seem the problem calls for any of those.

更新:我稍微改进了实现,与最初的相比,内容实际上会作为纸张从打印机中滑出标题而不是简单地被揭开,并且还消除了误报装订循环警告的来源.

Update: I slightly refined the implementation, compared to the initial one the content would actually slide out of the header as paper out of printer rather than simply being unveiled, and also removed the source of a false positive binding loop warning.

这篇关于如何在 QtQuick/QML 中创建动画、可变大小的手风琴组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆