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

查看:429
本文介绍了如何在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天全站免登陆