【问题标题】:Invert ListView without filling the ListView from the bottom反转 ListView 而不从底部填充 ListView
【发布时间】:2015-02-13 09:38:40
【问题描述】:

我希望 ListView 反转其项目的顺序,以便最近的项目位于顶部。 我尝试使用verticalLayoutDirection: ListView.BottomToTop 来实现这一点,但它会使 ListView 从底部填满(我猜是意料之中的)。

我将所述 ListView 的实际边界标记为红色。

我怎样才能颠倒 ListView 的项目顺序并且仍然让它从上到下填充?越干净越好。

根据要求,提供更多信息:

ListView
{
    id: theList

    anchors
    {
        left: parent.left
        top: theAboveList.bottom
        right: parent.right
        bottom: parent.bottom
    }

    model: theModel
    delegate: theDelegate {}
    verticalLayoutDirection: ListView.BottomToTop
    clip: true
}

我需要反转它的原因是,委托实例知道它们何时处于最底部(我可以在委托中执行index === 0),以设置特定状态。

【问题讨论】:

  • 嗯,解决起来应该不难,但实际上取决于您的用例:如何填充列表,使用的模型等等。只需尝试添加更多信息和列表的当前代码。
  • 我用更多信息更新了这个问题。

标签: listview qml qt-quick


【解决方案1】:

如果我理解正确,我想到的第一个想法是使用模型并操作来自C++ Qt side 的模型。但这项任务需要更多的耐心,并且会带来一点点开销。

另一种方法是将模型作为典型的 JavaScript 列表来操作——填充它,然后手动反转。

代码很简单:

function swap(a, b) {
    if (a < b) {
        move(a, b, 1)
        move (b-1, a, 1)
    } else if (a > b) {
        move(b, a, 1)
        move (a-1, b, 1)
    }
}

function reverse() {
    for (var i = 0; i < Math.floor(count/2); ++i) {
        swap(i, count-i-1)
    }
}

在这里你可以找到我写的AdvancedListModel的源代码——https://github.com/troyane/StackOverflow-pro/tree/master/AdvModel_qml

【讨论】:

    【解决方案2】:

    另一种解决方案是使用ListModelinsert method。在已经存在的索引中插入一个值不会压缩先前的值。它会改变它。

    这是一个例子:

    myModel.append({myValue: "Hello"})
    myModel.insert(0, {myValue: "Goodbye"})
    

    输出:

    Goodbye
    Hello
    

    【讨论】:

      【解决方案3】:

      我现在通过将 ListView 的高度属性设置为 contentHeight 解决了这个问题。由于可能的布局问题(绑定循环等),我最初想避免使用此解决方案,但现在必须这样做。

      【讨论】:

      • 这仅在模型足够短以至于所有代表都适合视图时才有效。一旦contentHeight 变得大于 ListView 的父级,它就会分崩离析。您是否设计了应对这种情况的方法?
      【解决方案4】:

      this other answer 为基础,但遵循它以便它适用于任何大小的模型,如果没有足够的视图填充视图,请使用header 组件中的间隔将代表推到顶部.

      import QtQuick 2.7
      import QtQuick.Controls 2.0
      import QtQuick.Layouts 1.0
      
      ApplicationWindow {
          visible: true
          width: 640
          height: 480
      
          property var theModel: 2
      
          Component {
              id: theDelegate
              Rectangle {
                  height: 100
                  border.width: 2
                  border.color: "black"
                  color: "red"
                  width: ListView.view.width
                  Text {
                      width: parent.width
                      text: index
                      font.pointSize: 30
                  }
              }
          }
      
          Item {
              id: theAboveList
              // component exists only to complete the example supplied in the question
          }
      
          ListView {
              id: theList
      
              anchors
              {
                  left: parent.left
                  top: theAboveList.bottom
                  right: parent.right
                  bottom: parent.bottom
              }
      
              model: theModel
              delegate: theDelegate
              verticalLayoutDirection: ListView.BottomToTop
              clip: true
      
              header: Item {}
              onContentHeightChanged: {
                  if (contentHeight < height) {
                      headerItem.height += (height - contentHeight)
                  }
                  currentIndex = count-1
                  positionViewAtEnd()
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-12-14
        • 1970-01-01
        • 2011-09-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-22
        相关资源
        最近更新 更多