[Solved] ListView: How to get snapped item when snaps occur?

  • I'm using a ListView that shows images. Only one image is visible at any time.

    I'm currently using ListView.SnapOneItem as snapMode, so when a user scrolls, the list moves only by one item at the time. But how can I find out which item is currently showing?

    Let's say that the currently visible item is the middle one in the list. From there I could drag the list so that it will snap to the previous item or to the next (or to neither of them, actually). Is there a way to get the index (or the item itself) of the element I'm scrolling to?

  • Moderators

  • The thing is, the ListView doesn't change the index when a user scrolls to another item.

    But let's say that I'm using a MouseArea and inside onClicked I do change the currentIndex to the item that it's currently pressed.

    Even with this information I don't know when the user will move to another item, and when he does I don't know if it will be to the previous item or to the next.

    So knowing the currentIndex (or actually the previous one, if the user moved) doesn't give me information on where he is now (not until he clicks on the image is currently watching, but I have to know which one is it as soon as the user moves).

  • Moderators

    One thing can be done is to use "onMovementEnded":http://qt-project.org/doc/qt-5/qml-qtquick-flickable.html#movementEnded-signal handler and there check the "verticalVelocity":http://qt-project.org/doc/qt-5/qml-qtquick-flickable.html#verticalVelocity-prop, it would positive or negative depending upon the direction. And since you are using ListView.SnapOneItem you can increment or decrement the currentIndex depeding upon its value.
    There could be another better solution though.

  • That's actually a great idea, thanks! I just tried and it works, now I can tell where the user moves to.

    Although there is one problem.

    If the user is dragging an image let's say to te left (I'm using a horizzontal list) but then he moves slightly to the right and releases the click, the movement will get canceled (and by that I mean that the ListView won't snap to another image but it will center the view to current one).

    When that happens though the horizzontalVelocity will be positive, letting me believe that the list moved to the right while it actually stayed where it was.

    Any ideas on how to find out if the movement is canceled?

  • Moderators

    AFAIK, there's none. But there's a workaround. You can store the "contentX":http://qt-project.org/doc/qt-5/qml-qtquick-flickable.html#contentX-prop value (Since you are using horizontal list) and compare the new contentX value with older one in the handler. If its the same then the ListView has not snapped to new image.

  • That's another good idea, it works :)

    But I found another problem regarding the horizzontalVelocity. I've seen that sometimes, if the movement is too fast and too sudden the horizzontalVelocity might be slightly above zero when it should be less than zero (or the contrary, in case the movement is in the opposite direction), and in that case it will say that the view moved in one direction while it's actually the opposite.

    But your idea of checking the contentX gave me another idea on how to check where the view moves to.

    Basically inside onMovementStarted I store the current contentX, and when the movement stops I check if the current contentX is less than the one I stored earlier; in that case it means that the view moved to the left, otherwise to the right (or if it's the same as before, as you said, it means it didn't move). This way I don't have the problem with sudden movements, or at least it appears that there aren't any for now.

    Thanks for the help!

  • Moderators

    You're Welcome :)
    Yes. It can be done in that way too. If you think the problem is solved you can edit the thread title and prepend [Solved] so that it would be helpful to others.

  • Sorry, I forgot to do that :D

Log in to reply

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.