ListView : Showing only current Item



  • Hi all

    I am using ListView to show video (MediaPlayer) information as a list. One Item on the whole screen. I need to load only one current item. Do not create other elements until we move on to it. And hide the previous one when moving.

    ListView {
        anchors.fill: parent
        focus: true
        interactive: false
        highlightFollowsCurrentItem: false
        highlightRangeMode: ListView.StrictlyEnforceRange
        snapMode: ListView.SnapOneItem
        cacheBuffer: 0
    
        // ...
    }
    

    But the element below is also created. How can this be avoided?



  • The view creates delegates as it wishes, you can't change that. You have to handle it in the delegate (which you didn't show). For example put something in a Loader which loads when ListView.isCurrentItem is changed. Read the documentation of ListView.

    If you want to show only one item at a time in the screen you could consider something else than a ListView. After all, it's meant to show several items in a list, not to fill the screen with one item.



  • main.qml

    import QtQuick 2.6
    import QtQuick.Window 2.2
    import QtQuick.Controls 1.4
    import QtQuick.Controls.Styles 1.4
    
    Window {
        id: window
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
        Item  {
            anchors.fill: parent
    
            ListModel {
                id: contact_model
                ListElement {
                    name: "Bill Smith"
                    color: "#555264"
                }
                ListElement {
                    name: "John Brown"
                    color: "#558426"
                }
                ListElement {
                    name: "Sam Wise"
                    color: "#255473"
                }
            }
    
            ListView {
                id: listView
                anchors.fill: parent
                focus: true
                interactive: false
                highlightFollowsCurrentItem: false
                highlightRangeMode: ListView.StrictlyEnforceRange
                snapMode: ListView.SnapOneItem
                cacheBuffer: 0
    
                model: contact_model
    
                delegate: Component {
    
                    Item {
                        id: delegate_item
                        height: window.height
                        anchors {
                            left: parent.left
                            right: parent.right
                        }
    
                        property bool isEmpty: true
    
                        onIsEmptyChanged: {
                            console.log(model.name)
                            em_loader.sourceComponent = new_item
                        }
    
                        Component.onCompleted: {
    
                            em_loader.sourceComponent = empty_item
                            /*if (index > 0) {
                            } else {
                                em_loader.sourceComponent = new_item
                            }*/
    
                        }
    
                        Loader {
                            id: em_loader
                            anchors.fill: parent
                        }
    
                        // empty
                        Component {
                            id: empty_item
                            Rectangle { anchors.fill: parent; color: "black" }
                        }
    
                        Component {
                            id: new_item
    
                            Item {
                                anchors.fill: parent
    
                                Rectangle { anchors.fill: parent; color: model.color }
    
                                Button {
                                    anchors.centerIn: parent
                                    text: model.name
                                    onClicked: {
                                        if (listView.currentIndex < listView.count - 1) {
                                            listView.currentItem.visible = false
                                            listView.incrementCurrentIndex()
                                            listView.positionViewAtIndex(listView.currentIndex, listView.model)
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
    
                onCurrentIndexChanged: {
                    if( !listView.moving)
                        transitionAnim.start()
    
                    console.log("CHANGED: " + listView.currentIndex)
                    //listView.model.get(listView.currentIndex).isEmpty = false
                    //listView.children[listView.currentIndex].isEmpty = false
                }
    
                SequentialAnimation {
                    id: transitionAnim
                    running: false
                    NumberAnimation { target: listView; property: "opacity"; from: 0; to: 1.0; duration: 800 }
                }
            }
        }
    }
    

    I created Loader and the default Component "empty_item". But I can not change the delegate.
    How get item delegate by index?



  • I found no other solution except to create a signal and check with the condition. I do not know how to send a signal to a specific delegate.
    But the problem can be considered solved. Thank you everyone.

    main.qml

    import QtQuick 2.6
    import QtQuick.Window 2.2
    import QtQuick.Controls 1.4
    import QtQuick.Controls.Styles 1.4
    
    Window {
        id: window
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
        Item  {
            anchors.fill: parent
    
            ListModel {
                id: contact_model
                ListElement {
                    name: "Bill Smith"
                    color: "#555264"
                }
                ListElement {
                    name: "John Brown"
                    color: "#558426"
                }
                ListElement {
                    name: "Sam Wise"
                    color: "#255473"
                }
            }
    
            ListView {
                id: listView
                anchors.fill: parent
                focus: true
                interactive: false
                highlightFollowsCurrentItem: false
                highlightRangeMode: ListView.StrictlyEnforceRange
                snapMode: ListView.SnapOneItem
                cacheBuffer: 0
    
                model: contact_model
    
                signal itemChanged()
    
                delegate: Component {
    
                    Item {
                        id: delegate_item
                        height: window.height
                        anchors {
                            left: parent.left
                            right: parent.right
                        }
    
                        Connections {
                            target: listView
                            onItemChanged: {
                                if (listView.currentIndex == index) {
                                    console.log("Index: " + listView.currentIndex + " : " + index)
                                    em_loader.sourceComponent = new_item
                                }
                            }
                        }
    
                        Component.onCompleted: {
                            em_loader.sourceComponent = empty_item
                        }
    
                        Loader {
                            id: em_loader
                            anchors.fill: parent
                        }
    
                        // empty
                        Component {
                            id: empty_item
                            Rectangle { anchors.fill: parent; color: "black" }
                        }
    
                        Component {
                            id: new_item
    
                            Item {
                                anchors.fill: parent
    
                                Rectangle { anchors.fill: parent; color: model.color }
    
                                Button {
                                    anchors.centerIn: parent
                                    text: model.name
                                    onClicked: {
                                        if (listView.currentIndex < listView.count - 1) {
                                            listView.currentItem.visible = false
                                            listView.incrementCurrentIndex()
                                            listView.positionViewAtIndex(listView.currentIndex, listView.model)
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
    
                onCurrentIndexChanged: {
                    if( !listView.moving) {
                        transitionAnim.start()
                    }
                    listView.itemChanged()
                }
    
                SequentialAnimation {
                    id: transitionAnim
                    running: false
                    NumberAnimation { target: listView; property: "opacity"; from: 0; to: 1.0; duration: 800 }
                }
            }
        }
    }
    

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.