Qt World Summit: Register Today!

ListView: position CurrentItem as last visible element?

  • Hello,

    When using highlightRangeMode: ListView.StrictlyEnforceRange the view will use preferredHighlightBegin and preferredHighlightEnd properties to position the currentItem in the relevant part of the visibileArea. However, it seems that it will favor preferredHighlightBegin over preferredHighlightEnd, i.e. if the item is larger than the indicated range, it will position it at preferredHighlightBegin and the item will span over preferredHighlightEnd. This is ok when you want to position the item at the beginning of the visibleArea, in the center, or somewhere inbetween. However, it becomes a problem when you want to display the currentItem as the last visible item and make sure the entire item is visible. A naive approach to achieve this would be:

    preferredHighlightBegin: width - currentItem.width
    preferredHighlightEnd: width

    This will lead to either binding loops or will make the view enter an infinite loop if items' width changes (for a horizontally oriented view). If items had the same width, that could be solved with:

    preferredHighlightBegin: width - constItemWidth
    preferredHighlightEnd: width

    But in my case, they don't have the same width. I was looking into this and found a solution, which is not as elegant as I would prefer. Namely, if layoutDirection: Qt.RightToLeft then preferredHighlightBegin and preferredHighlightEnd are reversed, i.e.

    preferredHighlightBegin: 0
    preferredHighlightEnd: currentItem.width

    results in currentItem being snapped to the list's visual end and view's behavior is stable even when items' width is changing (for example, when zooming in/out). However, of course, the order of items from the model is reversed as well, e.g. if items in the model are in ascending order they will be displayed in descending order. So the not-so-elegant solution is to reverse the order of items in the model. That would solve my visual-alignment issues, but require me to change the underlying model in a non-trivial way.

    Is there a better way of solving this? Perhaps without changing the layoutdirection. One important note - the current item is never the last item in the model, there are always items after it, which are not visible and when the model is scrolled through, more items are added.