实现一个可视化排序列表组件 SortableList
,适用于:
自定义内容排序(如模块、题目、选项)
拖拽交互排序项,支持长按或立即拖动
实时同步排序结果给外部父组件
拖动过程支持视觉反馈(放大、阴影、占位符)
可拓展为网格排序、双向拖动、远程同步
[ ▤ 题目A ]
[ ▤ 题目B ]
[ ▤ 题目C ] ← 拖动排序,释放后更新顺序
@Component
export struct SortableList {
@Prop items: Array = []
@Prop onUpdate: (newList: string[]) => void = () => {}
@State dragIndex: number = -1
@State overIndex: number = -1
@State innerList: string[] = [...this.items]
build() {
Column({ space: 8 }) {
this.innerList.forEach((item, index) => {
const isDragging = index === this.dragIndex
const isOver = index === this.overIndex && this.dragIndex !== -1
Row()
.height(40)
.padding({ left: 12, right: 12 })
.backgroundColor(isDragging ? '#e0f7ff' : isOver ? '#f0f0f0' : '#ffffff')
.borderRadius(6)
.shadow(isDragging ? { radius: 6, color: '#00000022' } : undefined)
.alignItems(VerticalAlign.Center)
.draggable({
data: index.toString(),
onDragStart: () => {
this.dragIndex = index
},
onDragEnter: () => {
if (index !== this.dragIndex) this.overIndex = index
},
onDrop: () => {
if (this.dragIndex !== -1 && this.overIndex !== -1 && this.dragIndex !== this.overIndex) {
const copy = [...this.innerList]
const [moved] = copy.splice(this.dragIndex, 1)
copy.splice(this.overIndex, 0, moved)
this.innerList = copy
this.onUpdate(copy)
}
this.dragIndex = -1
this.overIndex = -1
}
}) {
Image($r('app.media.icon_sort')).width(16).height(16).margin({ right: 8 })
Text(item).fontSize(14).fontColor('#333')
}
})
}
}
}
@Entry
@Component
struct DemoSortableList {
@State questionOrder: string[] = ['题目A', '题目B', '题目C', '题目D']
build() {
Column({ space: 20 }) {
SortableList({
items: this.questionOrder,
onUpdate: (list: string[]) => this.questionOrder = list
})
Text(`当前顺序:${this.questionOrder.join(' > ')}`)
.fontSize(13).fontColor('#888').margin({ top: 12 })
}.padding(20)
}
}
功能 | 说明 |
---|---|
拖动排序 + 删除按钮 | 拖动之外,每项支持右侧“删除”按钮 |
拖动手柄限制拖动区域 | 限定只能点击图标或左侧才能拖动 |
排序后同步后端数据 | onUpdate 回调后提交 API 接口 |
网格排序(Wrap + 拖动) | 拓展为宫格式拖动排序,适配图片/组件模块管理场景 |
第38篇:【HarmonyOS 5.0.0 或以上】构建分布式设备选择组件 DevicePicker:展示可用设备列表 / 自动发现 / 点击投送