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

Trying to center items programmatically in a ListView

我希望在 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 个项目),我希望第 3 个项目位于ListView 等左右两栏。这可能吗?在这个问题的范围之外,为什么 Transitions 也不起作用,例如?

我还根据评论提示设置了 highlightRangeMode: ListView.ApplyRange

问题截图如下:

这里的问题是您试图根据需要安排 ListView 代表。这是完全错误的,因为根据 ListView 大小 ,ListView(与所有其他视图非常相似)旨在为您做到这一点。 ListView 始终 使用 所有 可用的 space,导致委托全部位于左侧,因为您经验丰富。

您应该限制 ListView 大小并将其放置在中心,而不是将行为强加给代表。然后,您可以利用 highlightRangeModepreferredHighlightBeginpreferredHighlightEnd 来确保当前 selected Item 位于列表的中心.此外,通过使用 StrictlyEnforceRange,您可以强制 selected Item 保持 always 在中心,这将导致 IMO 更好的方法select 所需的 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"
        }
    }
}