PDA

View Full Version : ListView in a ScrollView: How to know scroll position (is it at bottom?)



ddonate
23rd June 2016, 09:53
Hi,

I have a WML application with a ScrollView and a ListView inside. The items from the ListView has variable height.

I need to know when the scroll bar is moved, in fact when it is at bottom and when it is NOT.

My target is to keep scroll at bottom (positionViewAtEnd()) when I add an item to the ListView ONLY if the scroll is at bottom. If NOT at bottom, positionViewAtEnd() will not be used.

I have tried "playing" with height, contentHeigh & contentY. Sometimes it works (when scroll is at bottom: contentHeight == contentY + height), but other times contentY value changes to negative values, and my code fails...

Any help?


Thanks a lot

Diego

anda_skoa
23rd June 2016, 10:23
A bit of code would help to understand what your situation actually looks like.

Do you use the ScrollView as a decorator on the ListView, i.e. as a means to provide a scrollbar for the ListView?
Or is the ListView on of the items inside the ScrollView's content item?

Cheers,
_

ddonate
23rd June 2016, 11:05
Thanks for your response.

I didn't add code since I am afraid I don't know what to add. I have just a ScrollView to provide a scrollbar for the ListView, as you said. I dind't specify that, sorry

The delegate displays incoming text in a kind of "bubbles", like a chat. Since the text is not fixed, the height of the ListView items (text messages) is variable.

Regards

anda_skoa
23rd June 2016, 13:14
Ok, so when the ListView is scrolled to the end, you want it to stay at the end, but if it is not, it should not move even if items are appended.
Does that sound right?

Cheers,
_

ddonate
23rd June 2016, 14:57
Exactly! ;)

anda_skoa
23rd June 2016, 15:52
Have you tried this with just the ListView alone?

How do you trigger your scrolling code?

What kind of model are you using?

Code would really help :)

Cheers,
_

ddonate
24th June 2016, 09:33
Hi,

I have tried with 'atYEnd' in several property changes, to detect if scroll is at bottom or not

It seems to work, and then I use that in 'onCountChanged' to put (or not) the scroll at the bottom

That works once all the ListView height is full of messages, but NOT in ONE case: when the incoming message is the one that fills the
ListView height (1st time that contentY is NOT '0').

I don't know if it is clear...

I have simplified my code to test (including the delegate), and now it seems like that:


FocusScope {
clip: true

id: focusScopeView

width: parent.width; height: parent.height

ScrollView {

width: parent.width; height: parent.height

ListView {
id: listTexts

width: parent.width; height: parent.height

property bool bScrolled: false

model: textsModel
delegate: Text { text: "Text:\t" + eventText }

onCountChanged: {

if (!bScrolled)
positionViewAtEnd();
}

onContentYChanged: {
bScrolled = !atYEnd;

if (atYEnd)
positionViewAtEnd()
}

onContentHeightChanged: {
if (!bScrolled)
positionViewAtEnd();
}
}
}
}

Thanks and regards!

Diego

anda_skoa
24th June 2016, 11:52
What you could try is this:

- have a property for "old content height"
- when content height grows, check if the old value is less than the visible height and the new value is greater than or equal, then you have filled the view.

Alternatively you could connect to the model's signals that indicate beginning of row changes (QAbstractItemModel::rowsAboutToBeInserted(), QAbstractItemModel::rowsAboutToBeRemoved()) and evaluate the situation for bScrolled there:
if content height is less than or equal the visible height or yAtEnd then scrolled is false

Cheers,
_