Master Details View con QML

November 22nd, 2010

Lo bueno de QML es que permite que casos de uso como una simple vista Maestro Detalle pueda ser mejorada agregando animaciones y layouts personalizados con muy poco esfuerzo.

El ejemplo a implementar es muy simple, vamos a usar un archivo XML como data source y para presentar los datos vamos a usar un GridView en donde seleccionaremos el item a mostrar en en el ListView que hace las veces de details view.

La acción central ocurren en el delegate usado para poblar el GridView el cual espera a que se haga click en alguno de los items, para pasar el index al ListView y disparar la animación que remueve el GridView de la escena para cambiar la opacidad del ListView de 0 a 1 para poder hacerlo visible, por ultimo hay en elemento Text que hará de botón para volver a la vista original.

import Qt 4.7

Rectangle {
    width: 360
    height: 640
    id:container

    XmlListModel {
        id: oranjeModel
        source: "http://localhost:3002/players.xml"
        query: "/players/player"
        XmlRole {
            name: "name"
            query: "name/string()"
        }
        XmlRole {
            name: "number"
            query: "number/string()"
        }
        XmlRole {
            name: "position"
            query: "position/string()"
        }
        XmlRole {
            name: "picture"
            query: "picture/string()"
        }
        XmlRole {
            name: "bio"
            query: "bio/string()"
        }
    }

    Component {
        id: oranjeDelegate
        Item {
            width: 80
            height: 110
            Image {
                source: picture
                width: parent.width
                height: parent.height
                fillMode: "Stretch"
                opacity: 0.5
            }
            MouseArea {
                anchors.fill: parent
                focus: true
                onClicked: {
                    oranjeDetails.currentIndex = index
                    container.state = "detailsView"
                }
            }
        }
    }

    Component {
        id: oranjeDetailsDelegate
        Grid {
            rows: 3
            spacing: 6

            Row {
                Image {
                    source: picture
                    width: 160
                    height: 230
                    fillMode: "Stretch"
                }

                Column {
                    Text {
                        text: number
                        font.pointSize: 24
                    }
                    Text {
                        text: name
                        font.pointSize: 18
                    }
                    Text {
                        text: position
                        font.pointSize: 14
                    }
                }
            }

            Row {
                Text {
                    text: bio
                    font.pointSize: 8
                    width: container.width
                    wrapMode: "Wrap"
                }
            }

            Row {
                Text {
                    text: "Back"
                    font.pointSize: 12
                    color: "#ed1e24"
                    width: container.width
                    MouseArea {
                        anchors.fill: parent
                        onClicked: container.state = ""
                    }
                }
            }

        }
    }

    GridView {
        id: oranjeList
        model: oranjeModel
        delegate: oranjeDelegate
        width: container.width
        height: container.height
        cellWidth:90
        cellHeight: 120
    }

    ListView{
        id: oranjeDetails
        model: oranjeModel
        delegate: oranjeDetailsDelegate
        opacity: 0
    }

    states: [
        State {
            name: "detailsView"
            PropertyChanges {
                target: oranjeList
                x: -container.width
            }
        }
    ]

    transitions: [
        Transition {
            from: ""
            to: "detailsView"
            NumberAnimation {
                properties: "x"
                easing.type: "OutBounce"
            }
            PropertyAnimation {
                target: oranjeDetails
                property: "opacity"
                to: 1
            }
        },
        Transition {
            from: "detailsView"
            to: ""
            NumberAnimation {
                properties: "x"
                easing.type: "OutSine"
                duration: 250
            }
            PropertyAnimation {
                target: oranjeDetails
                property: "opacity"
                to: 0
            }
        }
    ]
}
Development, User Interface , , No response

Comment now!