回复
Grid实现拖拽交换排序 原创
一路向北545
发布于 2024-12-14 17:12
浏览
0收藏
一、介绍
Grid 网格元素拖拽交换功能的实现,依靠的是 Grid 容器组件、组合手势以及显式动画这三者的结合。其中,Grid 容器组件的作用在于构建网格元素布局;组合手势的用途是达成元素拖拽交换的效果;显式动画则是为元素拖拽交换过程增添动画效果。
二、预览效果
三、实现步骤
(1)创建数据作为Grid的数据来源
@State data: string[] = []
aboutToAppear(): void {
for (let index = 0; index < 9; index++) {
this.data.push(`Item${index}`)
}
}
(2)Grid加载数据源显示UI
Grid() {
ForEach(this.data, (item: string) => {
GridItem() {
Text(item)
.width(100)
.height(100)
.border({ width: 1, color: Color.Grey })
.borderRadius(8)
.textAlign(TextAlign.Center)
}
})
}
.columnsGap(10)
.rowsGap(10)
.height(320)
.columnsTemplate('1fr 1fr 1fr')
(3)第一次拖拽此事件绑定的组件时,触发回调。
.onItemDragStart((event: ItemDragInfo, itemIndex: number) => {
return this.pixelMapBuilder(this.data[itemIndex]); //设置拖拽过程中显示的组件
})
@Builder
pixelMapBuilder(item: string) { //拖拽过程样式
Column() {
Text(item)
.width(120)
.height(120)
.border({ width: 1, color: Color.Grey })
.borderRadius(8)
.textAlign(TextAlign.Center)
.backgroundColor(Color.Yellow)
}
}
(4)拖拽结束逻辑处理
.onItemDrop((event: ItemDragInfo, itemIndex: number, insertIndex: number, isSuccess: boolean) => {
if (!isSuccess || insertIndex >= this.data.length) {
return
}
//itemIndex拖拽起始位置,insertIndex拖拽插入位置
this.changeIndex(itemIndex, insertIndex)
})
isSuccess=false时,说明drop的位置在grid外部;insertIndex > length时,说明有新增元素的事件发生,此种情况不做处理
(5)交换数组位置以实现排序效果
changeIndex(index1: number, index2: number) { //交换数组位置
let tmp = this.data.splice(index1, 1);
this.data.splice(index2, 0, tmp[0])
}
四、注意事项
(1)设置Grid是否进入编辑模式需要设置 editMode(true) ,进入编辑模式可以拖拽Grid组件内部GridItem
(2)内容排序动画需要设置 supportAnimation(true),否则会没有动画
(3)当拖拽的item在Grid外部时的情况需要排除掉,不然排序会错乱
五、完整代码
@Entry
@Component
struct Index {
@State data: string[] = []
aboutToAppear(): void {
for (let index = 0; index < 9; index++) {
this.data.push(`Item${index}`)
}
}
changeIndex(index1: number, index2: number) { //交换数组位置
let tmp = this.data.splice(index1, 1);
this.data.splice(index2, 0, tmp[0])
}
build() {
Column() {
Grid() {
ForEach(this.data, (item: string) => {
GridItem() {
Text(item)
.width(100)
.height(100)
.border({ width: 1, color: Color.Grey })
.borderRadius(8)
.textAlign(TextAlign.Center)
}
})
}
.columnsGap(10)
.rowsGap(10)
.height(320)
.columnsTemplate('1fr 1fr 1fr')
.supportAnimation(true)
.editMode(true) //设置Grid是否进入编辑模式,进入编辑模式可以拖拽Grid组件内部GridItem
.onItemDragStart((event: ItemDragInfo, itemIndex: number) => { //第一次拖拽此事件绑定的组件时,触发回调。
return this.pixelMapBuilder(this.data[itemIndex]); //设置拖拽过程中显示的图片。
})
.onItemDrop((event: ItemDragInfo, itemIndex: number, insertIndex: number, isSuccess: boolean) => {
if (!isSuccess || insertIndex >= this.data.length) {
return
}
this.changeIndex(itemIndex, insertIndex)
})
}
.height('100%')
.width('100%')
.padding(10)
.justifyContent(FlexAlign.Center)
.alignItems(HorizontalAlign.Center)
}
@Builder
pixelMapBuilder(item: string) { //拖拽过程样式
Column() {
Text(item)
.width(120)
.height(120)
.border({ width: 1, color: Color.Grey })
.borderRadius(8)
.textAlign(TextAlign.Center)
.backgroundColor(Color.Yellow)
}
}
}
©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
赞
收藏
回复
相关推荐