如何确定ScrollView中ListView的滚动位置

问题描述 投票:0回答:3

我有一个 QML 应用程序,里面有一个 ScrollView 和一个 ListView。 ListView 中的项目具有可变高度。

我需要知道滚动条何时移动,事实上,它何时位于底部以及何时。我的目标是当我将项目添加到 ListView

only
(如果滚动位于底部)时,将滚动条保持在底部(positionViewAtEnd())。如果不在底部,
positionViewAtEnd()
将不会被使用。

我尝试过用

height
contentHeight
contentY
“玩”。有时它有效(当滚动位于底部时:
contentHeight == contentY + height
),但其他时候,
contentY
值更改为负值,并且我的代码失败。

我如何实现这一目标?


我尝试过在几个属性更改中使用

atYEnd
来检测滚动条是否位于底部。

它似乎有效,然后我在

onCountChanged
中使用它来将(或不)滚动条放在底部。

一旦所有 ListView 高度都充满消息,就可以工作,但 notone 情况下:当传入消息是填充 ListView 高度的消息时(

contentY
第一次是 not
0
) .

我简化了要测试的代码(包括委托):

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: "Contact:\t" + eventText }

            onCountChanged: {

                if (!bScrolled)
                     positionViewAtEnd();
            }

            onContentYChanged: {
                bScrolled = !atYEnd;

                if (atYEnd)
                    positionViewAtEnd()
            }

            onContentHeightChanged: {
                if (!bScrolled)
                     positionViewAtEnd();
            }
        }
    }
}
listview scroll position qml scrollview
3个回答
1
投票

计算失败的原因是由于委托高度可变,

ListView
不得不调整其原点。在计算中包含 originY 将有助于获得正确的值,但是有一种更方便的方法来检查是否有任何
Flickable
atYEnd

编辑:这是一个技巧,但进行自动滚动(或者更确切地说,避免滚动的需要)的另一种方法是使用

ListView.BottomToTop
作为垂直布局方向。然后,如果追加到末尾,则在模型的开头插入新消息。这样,当新消息到达时,内容会保持底部对齐,而无需进行任何手动定位。不过,有一个小问题。当内容少于视图中的内容时,内容也会与底部对齐。


1
投票
  ListView {
        onContentYChanged: {
             if (contentY === contentHeight - height) {
               console.log("scrolled to bottom");
             }
        }
    }


    ScrollView {
            flickableItem.onContentYChanged: {
                if (flickableItem.contentY === flickableItem.contentHeight - viewport.height) {
                    console.log("scrolled to bottom");
                }
            }
        }

1
投票
ListView { 
        ScrollBar.vertical: ScrollBar {
                id: taskScroll
            }
        property bool atBottom: (taskScroll.position + taskScroll.size) == 1
    }
© www.soinside.com 2019 - 2024. All rights reserved.