Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Can't get my ListView Scrollbehavior correct in my simple example
QtWS25 Last Chance

Can't get my ListView Scrollbehavior correct in my simple example

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
2 Posts 1 Posters 761 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Offline
    L Offline
    LowLevelM
    wrote on last edited by LowLevelM
    #1

    cross-posted from: https://stackoverflow.com/questions/57079018/qml-cant-get-my-listview-scrollbehavior-correct-in-my-simple-example

    Its my first time to use ListView and i need to implement a decent scroll behavior for my application
    it "works" but sometimes the animation behavior is a little bit strange

    I've wrote a small QML example (runnable with qmlscene tool) to show my problem

    alt text

    Sample source code:

    import QtQuick 2.2
    import QtQuick.Window 2.5
    
    Window {
        width: 500
        height: 700
        visible: true
    
        // my model ctrl is in C++
        // faked it here with pure QML to simplify the example
        ListModel {
            id: cppModel
            // different size - item type depdendend (just const here)
            ListElement { name: "Item 1"; active: false; height: 50 }
            ListElement { name: "Item 2"; active: false; height: 100 }
            ListElement { name: "Item 3"; active: false; height: 150 }
            ListElement { name: "Item 4"; active: false; height: 200 }
            ListElement { name: "Item 5"; active: false; height: 250 }
            ListElement { name: "Item 6"; active: false; height: 300 }
    
            property int currentItemIndex: -1
    
            function activate_item(index) {
                // auto deactivate all others
                for(var i = 0; i < rowCount(); i++) {
                    var active = (index === i)
                    get(i).active = active
                    if(active) {
                        currentItemIndex = i
                    }
                }
            }
        }
    
        Component {
            id: listViewDelegate
    
            Rectangle
            {
                height: model.active ? model.height : 30
                width: 600
                color: "transparent"
                border {color: model.active ? "yellow" : "black"; width: 2}
    
                Behavior on height {
                    NumberAnimation {
                        easing.type: Easing.InCirc
                        duration: 5000
                    }
                }
    
                Text {
                    text: model.name;
                    font.pixelSize: 24
                }
    
                MouseArea {
                    anchors.fill: parent
                    onClicked: {
                        cppModel.activate_item(model.index)
                    }
                }
            }
        }
    
        Rectangle
        {
            width: 400
            height: 600
            border {color: "steelblue"; width: 2}
    
            ListView {
                id: myList
                anchors.fill: parent
                clip: true
                model: cppModel
                delegate: listViewDelegate
    
                header: Rectangle {
                    width: parent.width; height: 50
                    border {color: "red"; width: 2}
                    Text {
                        anchors.centerIn: parent
                        text: "Header"
                        font.pixelSize: 32
                    }
                }
    
                highlightMoveDuration: 5000
                highlightMoveVelocity: -1
                highlightResizeDuration: 5000
                highlightResizeVelocity: -1
    
                preferredHighlightBegin: 0
                preferredHighlightEnd: currentItem.height
                highlightRangeMode: ListView.StrictlyEnforceRange
    
                snapMode: ListView.SnapToItem
    
                currentIndex: -1
    
                onMovementStarted: {
                    // show header again
                    highlightRangeMode = ListView.ApplyRange
                }
                onCurrentIndexChanged: {
                    // highlight current
                    highlightRangeMode = ListView.StrictlyEnforceRange
                }
            }
    
            Connections {
                target: cppModel
                onCurrentItemIndexChanged: { // change comming from C++
                    if ( myList.currentIndex !== cppModel.currentItemIndex ) {
                        myList.currentIndex = cppModel.currentItemIndex
                    }
                }
            }
        }
    }
    

    first: the item that is activated should be scrolled to top (that works) seems ok, only the animation i get are a little strange

    my 2 "bad" animation scenarios:

    if you activate Item 1..6 downwards, starting with Item 3 the Item Text is moved too far up and then comes back, the up scrolling should always stop at the items top, no bouncing etc. - i've already tried to replace the highlighter but gives me no better result

    if you open for example Item 6 and the scroll with mouse to Item 1 and activates item 1, the animation (seems to) first closes the Item 6 and then scrolls the list, better would be that the scrolling/and resize to the activated item 1 is prio and the closing animation of the former item does not block/stutter the item 1 animation

    would be glad if someone could kick me in the right direction how to solve the animation problems

    thanks

    1 Reply Last reply
    0
    • L Offline
      L Offline
      LowLevelM
      wrote on last edited by LowLevelM
      #2

      a played a while with the ListView options but can't get the animations right
      so i've tried to implement my own list view like item - as an example how the animation would feel

      working sample, with an fake c++ model, with the animations i want to see

      import QtQuick 2.5
      import QtQuick.Controls 2.5
      import QtQuick.Window 2.5
      
      Window {
          width: 500
          height: 700
          visible: true
      
          // my model ctrl is in C++
          // faked it here with pure QML to simplify the example
          ListModel {
              id: cppModel
              // different size - item type depdendend (just const here)
              ListElement { name: "Item 1"; active: false; height: 100 }
              ListElement { name: "Item 2"; active: false; height: 150 }
              ListElement { name: "Item 3"; active: false; height: 200 }
              ListElement { name: "Item 4"; active: false; height: 250 }
              ListElement { name: "Item 5"; active: false; height: 300 }
              ListElement { name: "Item 6"; active: false; height: 350 }
      
              property int currentItemIndex: -1
      
              function activate_item(index) {
                  // auto deactivate all others
                  for(var i = 0; i < rowCount(); i++) {
                      var active = (index === i)
                      get(i).active = active
                      if(active) {
                          currentItemIndex = i
                      }
                  }
              }
      
              function remove_item(index) {
                  if(currentItemIndex === -1) {
                      console.log("can remove not active item")
                      return
                  }
      
                  remove(currentItemIndex);
              }
      
              function deactivate_current_item()
              {
                  if(currentItemIndex === -1) {
                      console.log("can remove not active item")
                      return
                  }
                  get(currentItemIndex).active = false
              }
          }
      
          Column {
      
              Rectangle {
                  width: 320
                  height: 480
      
                  border { width: 2; color: "steelblue" }
      
                  Flickable {
                      id: flickable
                      clip: true
                      anchors.fill: parent
                      contentWidth: 320
                      contentHeight: 600
      
                      function goto_header()
                      {
                          contentY = 0
                      }
      
                      Behavior on contentY {
                          NumberAnimation {
                              easing.type: Easing.OutCubic
                              duration: 500
                          }
                      }
      
                      Rectangle {
                          id: myList
      
                          anchors.top: parent.top
                          anchors.left: parent.left
                          width: flickable.contentWidth
                          height: flickable.contentHeight
      
                          Column {
                              Rectangle {
                                  id: header
                                  width: 320
                                  height: 40
                                  color: "red"
                                  border { width: 2; color: "black" }
                                  Text { text: "Header"}
                              }
      
                              Repeater {
                                  model: cppModel
                                  Rectangle {
                                      readonly property int reducedSize: 30
                                      width: 320
                                      height: model.active ? model.height : reducedSize
                                      border { width: 2; color: "black" }
                                      Text {
                                          text: model.name
                                      }
      
                                      MouseArea {
                                          anchors.fill: parent
                                          onClicked: {
                                              // find new list contentY
                                              // works also if item above is shrinking
                                              // but only if shrinked height is for all items the same
                                              var newContentY = (model.index * reducedSize) + header.height
      
                                              cppModel.activate_item(model.index)
      
                                              // scroll to this element
                                              flickable.contentY = newContentY
                                          }
                                      }
      
                                      Behavior on height {
                                          NumberAnimation {
                                              easing.type: Easing.OutCubic
                                              duration: 500
                                          }
                                      }
                                  }
                              }
                          }
                      }
                  }
              }
      
              Rectangle {
                  height: 100
                  width: 320
      
                  Row
                  {
                      Button {
                          text: "Delete"
                          onClicked: {
                              console.log("Delete clicked")
                              cppModel.remove_item();
                              flickable.goto_header();
                          }
                      }
                      Button {
                          text: "Save"
                          onClicked: {
                              console.log("Save clicked")
                              cppModel.deactivate_current_item()
                          }
                      }
                  }
              }
          }
      }
      
      

      Screenshot of the sample program

      0_1563517642889_Screenshot from 2019-07-19 08-27-03.png

      1 Reply Last reply
      0

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved