2016-11-24 11 views
4

これに続いて、この簡単なコードを書いています。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" } 
      } 
     } 
    } 
} 

Iを押すとItemに保持している場合、私は素敵な移動効果を持つ他のとそれを交換することができます。
リストに多数の項目があり、ターゲットの位置が表示可能な項目を超えている場合に問題が発生します。私はアイテムの広告をドラッグすることができます右または左の境界線の近くに移動...ここでは、移動効果は絶対にいいです。

アイテムが国境の近くに到着したときにリストを正しくスクロールするためのベストプラクティスはありますか?
アイテムがボーダーに触れる前にスクロールを開始したいと思います!

素敵な1

The nice one

ListView.currentIndexが変更された悪いもの

The bad one

答えて

2

ListViewスクロールします。これは、ドロップエリア内の最後の行です:

timeline.currentIndex = dragArea.DelegateModel.itemsIndex 

常に表示され、現在のインデックスは、ドラッグしたアイテムであると言います。しかし、ドラッグされたアイテムが境界線に到着した場合、ユーザはドラッグされたアイテムだけでなくその隣のアイテムも見ることを期待する。したがって、あなたはcurrentIndex 1つ以上の項目を追加する必要があります:あなたは右の境界にアイテムをドラッグした場合

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 
     } 
    } 
} 
関連する問題