Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make ListView items height dynamic based on inner content?

In following listview's items, length of text can be different (10, or 1000 characters), so I want make each list view item height fit text height. (Like css height: auto).

 Component {
        id: sysNotificationsDelegate        
        Rectangle {
            anchors.left: parent.left
            anchors.right: parent.right
            height: childrenRect.height                        
            color: "#eee"        
            Text {        
                text: model.body // <-- TEXT SIZE CAN BE DIFFERENT     
                wrapMode: Text.WordWrap
            }
        }
    }


ListView {
       anchors.fill: parent            
       spacing: 10

       model: ListModel {
           id: listModel
       }
       delegate: sysNotificationsDelegate    
}

What is proper and most performant way to achieve this? (taking into account that I will have a lot of such elements and I've read that property bindings in qml have some additional performance cost)

(Qt 5.10)

like image 934
Teimuraz Avatar asked Apr 09 '18 22:04

Teimuraz


1 Answers

For a Text to be able to wrap (or elide), it needs to have a width set, otherwise it will expand with no limit.

Text has 3 important width properties:

  • width: consider it the max width of a line of your text, it should always be set unless you don't want to limit the width of your screen (you can scroll or pan horizontally). Setting wrapMode or elide with no width will have no effect.
  • implicitWidth: the width the text would need to occupy to fit in a single line. Includes the left and right padding. Does not depend on the explicit width. Not sure when to use it ¯\_(ツ)_/¯ any ideas in the comments?
  • contentWidth: the width the text is actually occupying taking in account the wrapping and eliding. Does not include the left and right padding. Depends on the explicit width. Use this to query the width of your text, like when you want to draw a box around some text (a chat bubble for example).

The same corresponding properties exist for height too. maximumLineCount can limit the height of a text in addition to an explicit height

That means that in your case you want to do:

Rectangle {
    anchors.left: parent.left
    anchors.right: parent.right
    height: text.contentHeight // contentHeight, height and implicitHeight are all the same here since there's no padding, no maximumLineCount and height isn't explicitely set                        
    color: "#eee"        
    Text {
        id: text
        text: model.body // <-- TEXT SIZE CAN BE DIFFERENT
        width: parent.width // remember, width = max width for Text
        wrapMode: Text.WordWrap
    }
}
like image 123
GrecKo Avatar answered Oct 21 '22 04:10

GrecKo