android - 在 GridView 中交换元素
问题描述
我正在编写一个 QML 程序,它本质上是一个 4x4 GridView,里面填充了编号的矩形。我希望能够:
从网格中交换两个元素,拖放
仅允许直接相邻元素的交换
我目前的问题是,一旦我将一个元素拖到另一个元素之上,整个网格就会调整位置,填充元素最初所在的位置。有什么方法可以避免该类型网格的自动调整行为?
我知道下面的一段代码可能是造成这种行为的原因,我只是不知道如何以适当的方式改变它。
DropArea {
anchors { fill: parent; margins: 15 }
onEntered: {visualModel.items.move(drag.source.visualIndex, delegateRoot.visualIndex)}
}
完整代码:
import QtQuick 2.0
import QtQml.Models 2.1
GridView {
id: root
width: 320; height: 480
cellWidth: 80; cellHeight: 80
displaced: Transition {
NumberAnimation { properties: "x,y"; easing.type: Easing.OutQuad }//Animação anima a transicao dos tiles
}
model: DelegateModel {
id: visualModel
model: ListModel {
id: colorModel
ListElement { color: "lightsteelblue" ; text: "1" }
ListElement { color: "lightsteelblue" ; text: "2" }
ListElement { color: "lightsteelblue" ; text: "3" }
ListElement { color: "lightsteelblue" ; text: "4" }
ListElement { color: "lightsteelblue" ; text: "5" }
ListElement { color: "lightsteelblue" ; text: "6" }
ListElement { color: "lightsteelblue" ; text: "7" }
ListElement { color: "lightsteelblue" ; text: "8" }
ListElement { color: "lightsteelblue" ; text: "9" }
ListElement { color: "lightsteelblue" ; text: "10" }
ListElement { color: "lightsteelblue" ; text: "11" }
ListElement { color: "lightsteelblue" ; text: "12" }
ListElement { color: "lightsteelblue" ; text: "13" }
ListElement { color: "lightsteelblue" ; text: "14" }
ListElement { color: "lightsteelblue" ; text: "15" }
ListElement { color: "transparent" }
}
delegate: MouseArea {
id: delegateRoot
property int visualIndex: DelegateModel.itemsIndex
width: 80; height: 80
drag.target: icon
Rectangle {
id: icon
Text {
text: model.text
font.pointSize: 30
anchors.centerIn: parent
}
width: 72; height: 72
anchors {
horizontalCenter: parent.horizontalCenter;
verticalCenter: parent.verticalCenter
}
color: model.color
radius: 3
Drag.active: delegateRoot.drag.active
Drag.source: delegateRoot
Drag.hotSpot.x: 36
Drag.hotSpot.y: 36
states: [
State {
when: icon.Drag.active
ParentChange {
target: icon
parent: root
}
AnchorChanges {
target: icon;
anchors.horizontalCenter: undefined;
anchors.verticalCenter: undefined
}
}
]
}
DropArea {
anchors { fill: parent; margins: 15 }
onEntered: {visualModel.items.move(drag.source.visualIndex, delegateRoot.visualIndex)}
}
}
}
}
解决方案
我尝试了一些东西,但这里和那里仍然很少有错误。希望能帮助到你。
import QtQuick 2.0
import QtQml.Models 2.1
GridView {
id: root
width: 320; height: 480
cellWidth: 80; cellHeight: 80
displaced: Transition {
NumberAnimation { properties: "x,y"; easing.type: Easing.OutQuad }//Animação anima a transicao dos tiles
}
model: DelegateModel {
id: visualModel
model: ListModel {
id: colorModel
ListElement { color: "lightsteelblue" ; text: "1" }
ListElement { color: "lightsteelblue" ; text: "2" }
ListElement { color: "lightsteelblue" ; text: "3" }
ListElement { color: "lightsteelblue" ; text: "4" }
ListElement { color: "lightsteelblue" ; text: "5" }
ListElement { color: "lightsteelblue" ; text: "6" }
ListElement { color: "lightsteelblue" ; text: "7" }
ListElement { color: "lightsteelblue" ; text: "8" }
ListElement { color: "lightsteelblue" ; text: "9" }
ListElement { color: "lightsteelblue" ; text: "10" }
ListElement { color: "lightsteelblue" ; text: "11" }
ListElement { color: "lightsteelblue" ; text: "12" }
ListElement { color: "lightsteelblue" ; text: "13" }
ListElement { color: "lightsteelblue" ; text: "14" }
ListElement { color: "lightsteelblue" ; text: "15" }
ListElement { color: "transparent" ; text:"" }
}
delegate: MouseArea {
id: delegateRoot
property bool held: false
property int visualIndex: DelegateModel.itemsIndex
width: 80; height: 80
drag.target: held ? icon : undefined
drag.axis: Drag.XAndYAxis
drag.minimumX: delegateRoot.x-75
drag.minimumY: delegateRoot.y-75
drag.maximumX: delegateRoot.x + 85
drag.maximumY: delegateRoot.y + 85
onPressed: {
held = true
icon.opacity = 0.5
}
onReleased: {
if (held === true) {
held = false
icon.opacity = 1
icon.Drag.drop()
} else {
//action on release
}
}
Rectangle {
id: icon
Text {
text: model.text
font.pointSize: 30
anchors.centerIn: parent
}
width: 72; height: 72
anchors {
horizontalCenter: parent.horizontalCenter;
verticalCenter: parent.verticalCenter
}
color: model.color
radius: 3
Drag.active: delegateRoot.drag.active
Drag.source: delegateRoot
Drag.hotSpot.x: 36
Drag.hotSpot.y: 36
states: [
State {
when: icon.Drag.active
ParentChange {
target: icon
parent: root
}
AnchorChanges {
target: icon;
anchors.horizontalCenter: undefined;
anchors.verticalCenter: undefined
}
}
]
}
DropArea {
anchors {
fill: parent
margins: 15
}
onDropped: {
var sourceNumber = colorModel.get(drag.source.visualIndex).text;
var targetNumber = colorModel.get(delegateRoot.visualIndex).text;
var sourceColor = colorModel.get(drag.source.visualIndex).color;
var targetColor = colorModel.get(delegateRoot.visualIndex).color;
colorModel.setProperty(drag.source.visualIndex, "text", targetNumber);
colorModel.setProperty(delegateRoot.visualIndex, "text", sourceNumber);
colorModel.setProperty(drag.source.visualIndex, "color", targetColor);
colorModel.setProperty(delegateRoot.visualIndex, "color", sourceColor);
}
}
}
}
}
推荐阅读
- python - 从 txt 文件中获取数组并在 python 中设置为构造函数参数
- python-3.x - 如何使用openpyxl将excel中列的宽度设置为单元格值的最大长度?
- sql-server - 如何将动态查询列写入 SQL Server 中的行?
- java - 动态切换 Caffeine Cache 上的记录统计信息
- python - 在 AlexNet (Keras) 中使用预训练权重的问题
- android - 当用户按下并出现键盘时,EditText 消失
- javascript - Dropzone以编程方式在div内不起作用
- c# - Xrm.Sdk Linq 与 Joins 和动态 where
- mysql - 如何连接两个 MySQL 表并检查第二个表中的行状态
- restheart - 无法启动 RestHeart Security