在拖放项目期间滚动项目

Posted

技术标签:

【中文标题】在拖放项目期间滚动项目【英文标题】:Scroll items during drag and drop an item 【发布时间】:2017-04-08 22:26:49 【问题描述】:

在Qt tutorial 之后,我编写了这个简单的代码。有一个水平的ListView,上面有一些简单的彩色矩形作为模型项的代表。

import QtQuick 2.5
import QtQuick.Window 2.0
import QtQml.Models 2.2

Window 
    visible: true
    width: 300
    height: 120
    title: qsTr("Hello World")

    Rectangle 
        anchors.fill: parent;

        ListView
            id: timeline
            anchors.fill: parent
            orientation: ListView.Horizontal
            model: visualModel
            delegate: timelineDelegate

            moveDisplaced: Transition 
                NumberAnimation
                    properties: "x,y"
                    duration: 200
                
            

            DelegateModel 
                id: visualModel
                model: timelineModel
                delegate: timelineDelegate
            

            Component 
                id: timelineDelegate


                MouseArea 
                    id: dragArea

                    width: 100; height: 100

                    property bool held: false

                    drag.target: held ? content : undefined
                    drag.axis: Drag.XAxis

                    onPressAndHold: held = true
                    onReleased: held = false

                    Rectangle 
                        id: content

                        anchors  horizontalCenter: parent.horizontalCenter; verticalCenter: parent.verticalCenter 
                        width: 100
                        height: 100

                        color: colore
                        opacity: dragArea.held ? 0.8 : 1.0

                        Drag.active: dragArea.held
                        Drag.source: dragArea
                        Drag.hotSpot.x: width / 2
                        Drag.hotSpot.y: height / 2

                        states: State
                            when: dragArea.held
                            ParentChange  target: content; parent: timeline 
                            AnchorChanges 
                                target: content
                                anchors  horizontalCenter: undefined; verticalCenter: undefined 
                            
                        
                    

                    DropArea 
                        anchors.fill: parent
                        onEntered: 
                            visualModel.items.move( drag.source.DelegateModel.itemsIndex, dragArea.DelegateModel.itemsIndex)
                            timeline.currentIndex = dragArea.DelegateModel.itemsIndex
                        
                    
                
            

            ListModel 
                id: timelineModel
                // @disable-check M16
                ListElement  colore: "blue" 
                // @disable-check M16
                ListElement  colore: "orange" 
                // @disable-check M16
                ListElement  colore: "red" 
                // @disable-check M16
                ListElement  colore: "yellow" 
                // @disable-check M16
                ListElement  colore: "green" 
                // @disable-check M16
                ListElement  colore: "yellow" 
                // @disable-check M16
                ListElement  colore: "red" 
                // @disable-check M16
                ListElement  colore: "blue" 
                // @disable-check M16
                ListElement  colore: "green" 
            
        
    

如果我按住 Item,我可以将它与另一个交换,并具有很好的移动效果。 当列表中有很多项目并且目标位置超出可见项目时,问题就开始了。我可以拖动item ad 将它移动到右或左边框附近...这里的移动效果绝对不好。

当项目到达边界附近时,是否有正确滚动列表的最佳做法? 我希望在项目接触边框之前开始滚动!

不错的

坏人

【问题讨论】:

【参考方案1】:

ListViewListView.currentIndex 更改时滚动。也就是放置区的最后一行:

timeline.currentIndex = dragArea.DelegateModel.itemsIndex

表示当前索引始终可见,是拖动的项目。但是,如果拖动的项目到达边界,用户不仅希望看到拖动的项目,还希望看到它旁边的项目。因此,您需要在currentIndex 中再添加一项:

timeline.currentIndex = dragArea.DelegateModel.itemsIndex + 1

现在,如果您将项目拖动到右边框,列表视图会正确滚动到右侧。为了使其在左右边框中都可用,我们需要对其添加一些数学运算:

MouseArea 
    id: dragArea

    property int lastX: 0
    property bool moveRight: false

    onXChanged: 
        moveRight = lastX < x;
        lastX = x;
    

    //....

    DropArea 
        anchors.fill: parent
        onEntered: 
            visualModel.items.move( drag.source.DelegateModel.itemsIndex, 
                                    dragArea.DelegateModel.itemsIndex)
            if (dragArea.moveRight)
                timeline.currentIndex = dragArea.DelegateModel.itemsIndex + 1
            else
                timeline.currentIndex = dragArea.DelegateModel.itemsIndex - 1
        
    

【讨论】:

【参考方案2】:

简单

MouseArea 
    id: dragArea

         onPositionChanged:
               
             listView.positionViewAtIndex(listView.indexAt(x,y),ListView.Center)
            

//.....


【讨论】:

以上是关于在拖放项目期间滚动项目的主要内容,如果未能解决你的问题,请参考以下文章

android在拖放时滚动

UITableView - 如何在拖放期间更改单元格的背景颜色?

C#在拖放时实现ListView中的自动滚动

在拖放期间重绘

使控件在拖放期间对拖动事件透明

Chrome F8/热键调试器在拖放操作期间中断