QML Listview selected item highlight on click

ListView provides so called "attached properties", i.e. properties available in the delegate for the list. Among them Listview.view is a reference to the list itself. It can be used to access currentIndex property and update it. Hence, to solve your issue just:

  1. Uncomment //id: contactDelegate.
  2. Set contactDelegate.ListView.view.currentIndex = index in the OnClick even handler.

For those who use highlighting on a ListView with a specific height (being: not 100% height filled):

Be sure to enable the clip property of the ListView, as else the highlight will still be visible outside the ListView's borders while scrolling.

ListView 
{
    clip: true    
}   

As discussed here: Hide the highlight of a ListView while scrolling


Answer provided by denoth: You need to add this line:

listview1.currentIndex = index 

It appears you need two solutions to your question:

  1. You want to be able to set the current item of the ListView when it's clicked
  2. You want to be able to know when the current selection changes

The Qt5 documentation says this about ListView mouse and touch handling:

The views handle dragging and flicking of their content, however they do not handle touch interaction with the individual delegates. In order for the delegates to react to touch input, e.g. to set the currentIndex, a MouseArea with the appropriate touch handling logic must be provided by the delegate.

Key input will work out-of-the-box but you'll need to explicitly catch the mouse/touch event on the delegate, and change the ListView.currentIndex value based on the index value of the selected delegate item.

Here's a full example:

import QtQuick 2.4
import QtQuick.Window 2.2

Window {
    width: 640
    height: 480
    visible: true

    ListModel {
        id: model
        ListElement {
            name:'abc'
            number:'123'
        }
        ListElement {
            name:'efg'
            number:'456'
        }
        ListElement {
            name:'xyz'
            number:'789'
        }
    }

    ListView {
        id: list
        anchors.fill: parent
        model: model
        delegate: Component {
            Item {
                width: parent.width
                height: 40
                Column {
                    Text { text: 'Name:' + name }
                    Text { text: 'Number:' + number }
                }
                MouseArea {
                    anchors.fill: parent
                    onClicked: list.currentIndex = index
                }
            }
        }
        highlight: Rectangle {
            color: 'grey'
            Text {
                anchors.centerIn: parent
                text: 'Hello ' + model.get(list.currentIndex).name
                color: 'white'
            }
        }
        focus: true
        onCurrentItemChanged: console.log(model.get(list.currentIndex).name + ' selected')
    }
}

It does the following things:

  • creates a simple list and model
  • uses a MouseArea item within the item delegate to update set the list.currentIndex = index which is a local var and unique to the selected item
  • listens for the onCurrentItemChanged event of the ListView to show how to access the current model item values
  • binds the text value of the currently selected item to the highlight item to show using the currently selected values elsewhere