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,
_
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions Inc. All rights reserved.