尝试以编程方式在 ListView 中将项目居中

问题描述 投票:0回答:1

我希望在 QML 中居中放置项目

ListView
,因此我添加了以下代码
ListView

import QtQuick 2.0
import QtMultimedia 5.5
import QtQuick.Controls 1.3
import QtQuick.Extras 1.4
import QtQuick.Layouts 1.2
import QtQuick.Window 2.2
import QtTest 1.1

Rectangle {
    id: ueKeypad

    width: ueMainColumnLayout.implicitWidth+2*radius
    height: ueMainColumnLayout.implicitHeight+2*radius

    color: "grey"

    radius: 8

    border.color: "#99c6f0"
    border.width: 4

    ColumnLayout {
        id: ueMainColumnLayout

        anchors.fill: parent
        anchors.margins: radius

        spacing: 4

        RowLayout {
            id: ueTextLayout

            Text {
                id: ueStaffLoginText

                text: qsTr("Staff Login")

                verticalAlignment: Text.AlignVCenter
                horizontalAlignment: Text.AlignHCenter

                font.family: "Padauk"
                textFormat: Text.RichText

                font.pointSize: 16
                font.bold: true

                color: ueKeypad.border.color

                Layout.fillWidth: true
            }   // ueStaffLoginText
        }   // ueTextLayout

        RowLayout {
            id: uePeopleViewLayout

            ListView {
                id: uePeopleView

                keyNavigationWraps: true

                spacing: 4

                antialiasing: true

                model: uePeopleModel

                Layout.fillWidth: true
                Layout.fillHeight: false

                //Layout.minimumWidth: 64
                Layout.minimumHeight: 64
                //Layout.preferredWidth: 96
                Layout.preferredHeight: 96
                //Layout.maximumWidth: 128
                Layout.maximumHeight: 128

                orientation: ListView.Horizontal
                layoutDirection: Qt.LeftToRight

                snapMode: ListView.SnapToItem

                highlightRangeMode: ListView.ApplyRange

                Component.onCompleted: {
                    var newIndex=(count%2==0)?(count/2):(Math.round(count/2));

                    positionViewAtIndex(newIndex, ListView.Center);
                    currentIndex=newIndex;
                    print(newIndex)
                }   // onCompleted - center items

                delegate: Rectangle {
                        id: uePersonDelegate

                        width: 32
                        height: 32

                        ColumnLayout {
                            id: uePersonDelegateMainLayout

                            anchors.fill: parent
                            anchors.margins: radius

                            RowLayout {
                                id: uePersonDelegateImageLayout

                                Image {
                                    id: uePersonImage

                                    antialiasing: true

                                    fillMode: Image.PreserveAspectFit

                                    source: "image://uePeopleModel/"+model.ueRoleImage
                                }   // uePersonImage
                            }   // uePersonDelegateImageLayout

                            RowLayout {
                                id: uePersonDelegateNameLayout

                                Text {
                                    id: ueTextPersonName

                                    color: "#ffffff"

                                    text: model.ueRoleName

                                    font.bold: true
                                    font.pixelSize: 16

                                    verticalAlignment: Text.AlignVCenter
                                    horizontalAlignment: Text.AlignHCenter
                                }   // ueTextPersonName
                            }   // uePersonDelegateNameLayout
                        }   // uePersonDelegateMainLayout
                    }   // uePersonDelegate

                add: Transition {
                    NumberAnimation {
                        property: "opacity";
                        from: 0;
                        to: 1.0;
                        duration: 100
                    }   // NumberAnimation

                    NumberAnimation {
                        property: "scale";
                        from: 0;
                        to: 1.0;
                        duration: 100
                    }   // NumberAnimation
                }   // Transition

                displaced: Transition {
                    NumberAnimation {
                        properties: "x,y";
                        duration: 100;
                        easing.type: Easing.OutBounce
                    }   // NumberAnimation
                }   // Transition
            }   // uePeopleView
        }   // uePeopleViewLayout

        RowLayout {
            id: ueTumblerLayout

            Tumbler {
                id: ueLoginKeypadTumbler

                Layout.fillWidth: true
                Layout.fillHeight: false

                height: 100

                antialiasing: true

                TumblerColumn {
                    id: ueNumericTumblerColumnDigit1000

                    model: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
                }   // ueNumericTumblerColumnDigit1000

                TumblerColumn {
                    id: ueNumericTumblerColumnDigit100

                    model: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
                }   // ueNumericTumblerColumnDigit100

                TumblerColumn {
                    id: ueNumericTumblerColumnDigit10

                    model: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
                }   // ueNumericTumblerColumnDigit10

                TumblerColumn {
                    id: ueNumericTumblerColumnDigit1

                    model: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
                }   // ueNumericTumblerColumnDigit1
            }   // ueLoginKeypadTumbler
        }   // ueTumblerLayout

        RowLayout {
            id: ueButtonsLayout

            Button {
                id: ueButtonLogin

                Layout.fillWidth: true

                text: qsTr("Login")
            }   // ueButtonLogin

            Button {
                id: ueButtonClear

                Layout.fillWidth: true

                text: qsTr("Clear")
            }   // ueButtonClear

            Button {
                id: ueButtonQuitApp

                Layout.fillWidth: true

                text: qsTr("Quit")
            }   // ueButtonQuitApp
        }   // ueButtonsLayout
    } // ueMainColumnLayout

    states: [
        State {
            name: "ueStateLoginOk"

            PropertyChanges {
                target: ueKeypad
                border.color: "#00ff00"
            }

            PropertyChanges {
                target: ueLoginText
                color: "#00ff00"
            }
        },  // ueStateLoginOk

        State {
            name: "ueStateLoginOkFailed"

            PropertyChanges {
                target: ueKeypad
                border.color: "#ff0000"
            }

            PropertyChanges {
                target: ueLoginText
                color: "#ff0000"
            }
        }   // ueStateLoginOkFailed
    ]   // states
}   // ueKeypad

现在,

print(newIndex)
语句打印出正确的值
3
(就我而言,因为目前我有5个项目),我希望第三个项目位于
ListView
的中心,其他两个项目位于左侧和右侧。这可能吗?超出了这个问题的范围,为什么
Transition
s 也不起作用,从例子来看?

我还设置了取自评论提示的

highlightRangeMode: ListView.ApplyRange

这是问题的截图:

qt qml qtquick2 qtquickcontrols qtquickextras
1个回答
11
投票

这里的问题是您试图根据您的需要放置

ListView
代表。这完全是错误的,因为
ListView
(就像所有其他视图一样)是为了为您做到这一点,根据
ListView
尺寸
ListView
始终使用所有可用空间,导致代表全部位于左侧,正如您所经历的那样。

不要将行为强加给代表,您应该限制

ListView
的大小并将其放置在中心。然后,您可以利用
highlightRangeMode
preferredHighlightBegin
这个答案
中的 preferredHighlightEnd 来确保当前选择的
Item
位于列表的中心。此外,通过使用
StrictlyEnforceRange
,您可以强制选定的
Item
保持 always 在中心,这将导致 IMO 更好地选择所需的
Item

这是实现此方法的示例。为了简单起见,尺寸是硬编码的,但可以轻松参数化。如前所述,我通过设置突出显示策略走得更远。希望有帮助。

import QtQuick 2.4
import QtQuick.Window 2.2
import QtQuick.Layouts 1.1

Window {
    id: win
    width: 300
    height: 300
    visible: true

    ColumnLayout {
        anchors.fill: parent

        Rectangle {
            Layout.fillWidth: true
            Layout.fillHeight: true
            color: "blue"
        }

        ListView {
            Layout.alignment: Qt.AlignCenter
            Layout.minimumWidth: 30 * 5 + 40
            Layout.preferredHeight: 50
            clip: true
            spacing: 15
            model: 10
            orientation: ListView.Horizontal
            delegate: Item {
                width: 30
                height: 50
                Rectangle{
                    anchors.centerIn: parent
                    color: parent.ListView.isCurrentItem ? "red" : "steelblue"
                    width: 30
                    height: 30
                    Text {
                        text: index
                        anchors.centerIn: parent
                    }
                    scale: parent.ListView.isCurrentItem ? 1.5 : 1
                    Behavior on scale { NumberAnimation { duration: 200 } }
                }
            }
            preferredHighlightBegin: width / 2 - 15
            preferredHighlightEnd: width / 2 + 15
            highlightRangeMode: ListView.StrictlyEnforceRange
            Component.onCompleted: currentIndex = count / 2
        }

        Rectangle {
            Layout.fillWidth: true
            Layout.fillHeight: true
            color: "yellow"
        }
    }
}

© www.soinside.com 2019 - 2024. All rights reserved.