September 14, 2011

Milnadar Milnadar
Lab Rat
26 posts

ListView’s flickable problems

Page  
1

Hi everyone.

I noticed that when (vertical) listView’s items has different height, contentHeight value doesn’t equal to height of all items. When changing ListView’s height, contentHeight may be larger or smaller than it should be. Why is it so? How does ListView count it’s contentHeight?
The same issue when items have different height, and i am swapping two items and trying to flick listView on item’s height by changing contentY value;

[edit : typo in title fixed, Eddy]

21 replies

September 15, 2011

Alicemirror Alicemirror
Lab Rat
825 posts

Hi, please can you post a piece of your code ? ListViews are objects that don’t need to implement the flickable mechanism because they are already flickable objects by default.

 Signature 

Enrico Miglino (aka Alicemirror)
Tech Consulting
Islas Baleares, Ibiza (Spain)
http://www.contesti.eu

September 15, 2011

Milnadar Milnadar
Lab Rat
26 posts

I understand that they are flickable objects. The problem is that if items have different height, the listView’s contentHeight is counted not correct;
Unfortunaly i am not able to post my code here, because it is to much of it, but i’ll try to post an example.
ListDelegate.qml

  1. Compenent{
  2.  Item{
  3.   height: edit.height
  4.   TextEdit{
  5.    id: edit
  6.    text: someText //(role)
  7.   }
  8.  }
  9. }

The sometext value may be multiline, so each delegate may have different height

September 15, 2011

Alicemirror Alicemirror
Lab Rat
825 posts

Mmmh… I see. The problem I think maybe in the text. As a matter of fact I have expereienced that the height of your edit example is not always correct if the text is higher. You should check the height of the text.

But, just to be clear, I understand that you don’t need to show your code, but this example is so simple. It is difficult to disucss about something that is not possible to see.

 Signature 

Enrico Miglino (aka Alicemirror)
Tech Consulting
Islas Baleares, Ibiza (Spain)
http://www.contesti.eu

September 15, 2011

Milnadar Milnadar
Lab Rat
26 posts

Thanks for your help. I think i found where my bug is. TextEdit height depends on paintedHeight value, and when list is scrolling it is “jumping” from one value to another. Is it because of that paintedHeight depends on visibility of the text on the screen?

September 15, 2011

Alicemirror Alicemirror
Lab Rat
825 posts

Partially true. The real text height depends on the font size and the number of characters. Then the program shows text with word wrap (I suppose yes in this case). This means that you can’t know before how much lines your text is really height. Thus you should manage the height of every list element based on the painted height. Eventually you can decide in your model to put a control like elide the test that exceeds the previous decided height or if the painted height exceeds the height of your list model you should remove lines or words from your sentence before it is shown.

 Signature 

Enrico Miglino (aka Alicemirror)
Tech Consulting
Islas Baleares, Ibiza (Spain)
http://www.contesti.eu

September 15, 2011

Milnadar Milnadar
Lab Rat
26 posts

Thanks again for help.

September 15, 2011

Milnadar Milnadar
Lab Rat
26 posts

Even if i set all delegates height to 20, and to one of them to 50, contentHeight value counts not correctly when scrolling the listView

September 15, 2011

Alicemirror Alicemirror
Lab Rat
825 posts

Thank you for this news. I had not experienced this condition but I am developing an application that can happen. So I manage it a workaround before.

 Signature 

Enrico Miglino (aka Alicemirror)
Tech Consulting
Islas Baleares, Ibiza (Spain)
http://www.contesti.eu

September 17, 2011

Milnadar Milnadar
Lab Rat
26 posts

I was thinking to set ContentHeight manually, by counting every item’s text’s length, and number of lines of text, but! ListView just ignores my value, and uses it’s own. :)
Is it ok?

September 17, 2011

Alicemirror Alicemirror
Lab Rat
825 posts

I think yes. The reason will be that you try setting the value of the element that is built automatically depending on the ListModel, where you define the aspect of the elements that formerly are part of the generic abstract representation of any element of the list.

ListView just fill the model based on the ListElements (or any other element i.e. the XmlList). I think that you should try to set the sizes in the ListModel. Thus when you define the model you don’t know yet what will be the size of that particular instance of the model when the ListView will fill it with the ListData. If in the model you create an area that changes depending on every element content I think that everything works fine.

A short advice in your case: if you set a text in a rectangle the object that you manage as the size reference is the rectangle, despite the text size. To avoid this problem you should do something like the following:

  1. Create a rectangle set with the initial width and height you want.
  2. Set the rectangle opacity to 0 if it should be hidden: you only need a fake object
  3. Create a text object and bind the rectangle height to the full text height: this means that depending by how much text you have the rectangle will be always height to contain it.
  4. Align the text object on top margin of the rectangle (one over the other)

Try it and let me know if it works. I you have some doubt I will try to create this kind of coupled object.

 Signature 

Enrico Miglino (aka Alicemirror)
Tech Consulting
Islas Baleares, Ibiza (Spain)
http://www.contesti.eu

September 17, 2011

Alicemirror Alicemirror
Lab Rat
825 posts

See the following example. Sorry but I get it from a more complex piece of code so I think it can’t work. BTW you can get the idea applying it in your code without difficult.

  1. // Login form for registered users
  2. Item {
  3.     id: login
  4.  
  5.     width: parent.width;
  6.     // Height is set based on the height value of the text area.
  7.     height: background.textHeight
  8.  
  9.     signal newuserClicked; signal loginClicked
  10.  
  11. [... some custom properties definition ...]
  12.  
  13.     // Main background recatngle with information text
  14.     Rectangle {
  15.         id: background
  16.         width: parent.width
  17.         property alias textHeight: textIntro.paintedHeight
  18.         height: parent.height
  19.         anchors.horizontalCenter: parent.horizontalCenter
  20.         anchors.bottom: parent.bottom
  21.         color: "#d1cece"; border.color: "#eeeeee";
  22.         border.width: Geometry.getFormBorder();
  23.         radius: Geometry.getRadius()
  24.         // Introductory text over the login area.
  25.         Text {
  26.             id: textIntro
  27.             width: background.width * 0.95; anchors.top: background.top
  28.             anchors.topMargin: 5;
  29.             anchors.horizontalCenter: background.horizontalCenter
  30.             color: "#ffffff"
  31.             wrapMode: TextEdit.Wrap; font.pointSize: Geometry.getFontPoints();
  32.             text: login.loginIntro
  33.         }
  34.     }
  35.  
  36. [... other stuff ...]
  37. }

Hope it can help you.

 Signature 

Enrico Miglino (aka Alicemirror)
Tech Consulting
Islas Baleares, Ibiza (Spain)
http://www.contesti.eu

September 17, 2011

Milnadar Milnadar
Lab Rat
26 posts

Or it is me who make it wrong, or i don’t know :)
As for rectangles and text inside of it, in my current code text is in rectangle already, and my delegate’s height depends on text height and if Loader component is loaded, it’s height added to delegate’s height, and there is also separator line to separate two types of items in the view; I thought that something in my current code is making contentHeight value “jumping”, so i just created small example project and test everything using it;
I also noticed that contentHeight value changed when item with higher height scrolls away or returns to screen; So i think that contentHeight depends on items visibility or smth.
p.s. tried to set item’s height from model – didn’t help
Here is example that i am using
ListDelegate.qml

  1. Component{
  2.     Item{
  3.         height: layout.height
  4.         Rectangle{
  5.             id: layout
  6.             height: index == 3 ? 50 : 20
  7.             TextEdit{
  8.                 id: edit
  9.                 height: paintedHeight
  10.                 font {pixelSize: 20}
  11.                 text: title
  12.             }
  13.         }
  14.     }
  15. }

ListModel.qml

  1.     ListModel{
  2.         id: model
  3.         ListElement{
  4.             title: "this is test text"
  5.         }
  6.         ListElement{
  7.             title: "World"
  8.         }
  9.         ListElement{
  10.             title: "Some more text"
  11.         }
  12.         ListElement{
  13.             title: "And some more :)"
  14.         }
  15.         ListElement{
  16.             title: "Dummy text"
  17.         }
  18.         ListElement{
  19.             title: "Dummy text"
  20.         }
  21.         ListElement{
  22.             title: "Dummy text"
  23.         }
  24.         ListElement{
  25.             title: "Dummy text"
  26.         }
  27.         ListElement{
  28.             title: "Dummy text"
  29.         }
  30.         ListElement{
  31.             title: "Dummy text"
  32.         }
  33.         ListElement{
  34.             title: "Dummy text"
  35.         }
  36.         ListElement{
  37.             title: "Dummy text"
  38.         }
  39.         ListElement{
  40.             title: "Dummy text"
  41.         }
  42.         ListElement{
  43.             title: "Dummy text"
  44.         }
  45.         ListElement{
  46.             title: "Dummy text"
  47.         }
  48.         ListElement{
  49.             title: "Dummy text"
  50.         }
  51.         ListElement{
  52.             title: "Dummy text"
  53.         }
  54.         ListElement{
  55.             title: "Dummy text"
  56.         }
  57.         ListElement{
  58.             title: "Dummy text"
  59.         }
  60.         ListElement{
  61.             title: "Dummy text"
  62.         }
  63.         ListElement{
  64.             title: "Dummy text"
  65.         }
  66.         ListElement{
  67.             title: "Dummy text"
  68.         }
  69.     }

main.qml

  1. import QtQuick 1.0
  2.  
  3. Rectangle {
  4.     width: 360
  5.     height: 360
  6.  
  7.     ListView{
  8.         id: view
  9.         anchors {fill: parent;}
  10.         spacing: 5
  11.         delegate: ListDelegate{}
  12.         model: ListModel{}
  13.         Rectangle{
  14.             anchors {fill: view.contentItem;}
  15.             color: "transparent"
  16.             border {color: "red"; width: 2;}
  17.         }
  18.         onContentYChanged: {console.log(contentHeight)}
  19.     }
  20. }

September 17, 2011

Milnadar Milnadar
Lab Rat
26 posts

Project from which you posted part of code, as i understand there are no problems with contentHeight?
Or they are just invisible? )

September 17, 2011

Alicemirror Alicemirror
Lab Rat
825 posts

This is the solution that I have adopted to solve the problem of content height.

Two strange things in your example: ListDelegate.qml is the ListItem ? It seems you have misunderstood the role of the three elements Item, Model and Delegate.

 Signature 

Enrico Miglino (aka Alicemirror)
Tech Consulting
Islas Baleares, Ibiza (Spain)
http://www.contesti.eu

September 17, 2011

Milnadar Milnadar
Lab Rat
26 posts

It’s probably when i say item i mean the item in the list, and when i say delegate, i mean the delegate. I think i do understand the role of three elements, and just build my sentences wrong.
Could you please explain what you find strange in that example?
ListDelegate.qml it is a delegate;

Page  
1

  ‹‹ QUiLoader Usage.      [Solved] QPushButton from C++ UI signal to rotate qml element ››

You must log in to post a reply. Not a member yet? Register here!