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 } } } } }
-
@alexorleon said in ListView : Showing only current Item:
delegate: Component {
Item { id: delegate_item height: window.height anchors { left: parent.left right: parent.right }
The children in the delegate Component should not fill it!
Remove the achors as well as heigh and width, and it will work. -
@alexorleon said in ListView : Showing only current Item:
delegate: Component {
Item { id: delegate_item height: window.height anchors { left: parent.left right: parent.right }
The children in the delegate Component should not fill it!
Remove the achors as well as heigh and width, and it will work.@ahmad-a said in ListView : Showing only current Item:
The children in the delegate Component should not fill it!
Why not?
-
@ahmad-a said in ListView : Showing only current Item:
The children in the delegate Component should not fill it!
Why not?
-
@grecko said in ListView : Showing only current Item:
the delegate Co
delegate represents each row. If its height is as main window height, it can only show one row!
changing to "height: 40" ,for example, will fix the problem.
@ahmad-a said in ListView : Showing only current Item:
delegate represents each row. If its height is as main window height, it can only show one row!
That's not a problem, it could be used to scroll between delegates taking all the screen. Like a photo gallery for example
-
Hi...
I have a similar problem exactly !
If you find a solution for it, let me know please..