1. 拖拽效果展示

2. 表格静态页面搭建
@State table: ListModel = new ListModel({
head: [{
title: '姓名',
name: 'name',
index: 0
}, {
title: '年龄',
name: 'age',
index: 1
}, {
title: '性别',
name: 'sex',
index: 2
}],
data: [
{ name: '张三', age: 20, sex: '男' },
{ name: '李四', age: 19, sex: '女' },
{ name: '王五', age: 20, sex: '男' },
{ name: '赵六', age: 17, sex: '女' },
{ name: '老高', age: 28, sex: '男' }]
})
- 新建viewModel文件夹 新建 List 文件定义数据类型
export interface List {
head: headItem[]
data: PeopleItem[]
}
export interface PeopleItem {
name: string
age: number
sex: "男" | "女"
}
export interface headItem {
title: string
name: string
index: number
}
export class ListModel implements List {
head: headItem[] = []
data: PeopleItem[] = []
constructor(model: List) {
this.head = model.head
this.data = model.data
}
}
export class PeopleItemModel implements PeopleItem {
name: string = ''
age: number = 0
sex: "男" | "女" = "男"
constructor(model: PeopleItem) {
this.name = model.name
this.age = model.age
this.sex = model.sex
}
}
export class headItemModel implements headItem {
title: string = ''
name: string = ''
index: number = 0
constructor(model: headItem) {
this.title = model.title
this.name = model.name
this.index = model.index
}
}
- 写出相应的ui布局,布局为表格类型list组件里循环表头列表,同时设置
.listDirection(Axis.Horizontal) 属性。为横向排列方式
build() {
Row() {
List() {
ForEach(this.table.head, (v: headItem, i: number) => {
ListItem() {
Column({ space: 20 }) {
Text(v.title)
.fontSize(25)
ForEach(this.table.data, (v2: PeopleItem, i2: number) => {
Row() {
Text((v2 as object)[v.name].toString())
}
})
}
.width('100%')
.backgroundColor(i % 2 === 1 ? '#fff67b7b' : '#ffffec69')
}
.backgroundColor('#ff87ecf5')
.width('33%')
})
}
.listDirection(Axis.Horizontal)
.width('100%')
.margin({
top: 100
})
}
.height('50%')
.width('100%')
}
3. 表格拖拽效果
getHeaderItemByIndex(index: number) {
return this.table.head.find(item => item.index === index)
}
@Builder
getDragItemList(index: number) {
Column() {
Text(this.getHeaderItemByIndex(index)?.title || "")
.backgroundColor(Color.Blue)
.fontColor(Color.White)
.height(50)
.width(120)
.textAlign(TextAlign.Center)
List() {
ForEach(this.table.data, (item: PeopleItem) => {
ListItem() {
Text((item as object)[this.getHeaderItemByIndex(index)?.name || ""].toString())
.fontColor(Color.White)
.width("100%")
.textAlign(TextAlign.Center)
}
.height(50)
})
}
.width(120)
}
.backgroundColor(Color.Gray)
}
List(){
....
}
.onItemDragStart((event: ItemDragInfo, itemIndex: number) => {
return this.getDragItemList(itemIndex)
})
- 当我们触发了移动列表元素,此时还需要设置 onItemDrop 属性,作用:当拖动的列表项松手释放后会触发回调
- 跨List拖拽时,当拖拽释放的位置绑定了onItemDrop时会返回true,否则为false。List内部拖拽时,isSuccess为onItemMove事件的返回值。所以我们拖动的列表需要为list内部才可以
changeListItemIndex(startIndex: number, toIndex: number) {
let startTarget = new headItemModel(this.table.head[startIndex]);
startTarget.index = toIndex
let toTarget = new headItemModel(this.table.head[toIndex])
toTarget.index = startIndex
this.table.head[startIndex] = startTarget;
this.table.head[toIndex] = toTarget;
this.table.head.sort((a, b) => a.index - b.index)
this.table.head = [...this.table.head]
}
List(){
....
}
.onItemDragStart((event: ItemDragInfo, itemIndex: number) => {
return this.getDragItemList(itemIndex)
})
.onItemDrop((event: ItemDragInfo, itemIndex: number, insertIndex: number, isSuccess: boolean) => {
if (!isSuccess || insertIndex >= this.table.head.length) {
return;
}
return this.changeListItemIndex(itemIndex, insertIndex)
})
4. 源代码
src/main/ets/pages/Index.ets
import { headItem, headItemModel, ListModel, PeopleItem } from '../models/List'
@Entry
@Component
struct Index {
@State table: ListModel = new ListModel({
head: [{
title: '姓名',
name: 'name',
index: 0
}, {
title: '年龄',
name: 'age',
index: 1
}, {
title: '性别',
name: 'sex',
index: 2
}],
data: [
{ name: '张三', age: 20, sex: '男' },
{ name: '李四', age: 19, sex: '女' },
{ name: '王五', age: 20, sex: '男' },
{ name: '赵六', age: 17, sex: '女' },
{ name: '老高', age: 28, sex: '男' }]
})
getHeaderItemByIndex(index: number) {
return this.table.head.find(item => item.index === index)
}
@Builder
getDragItemList(index: number) {
Column() {
Text(this.getHeaderItemByIndex(index)?.title || "")
.backgroundColor(Color.Blue)
.fontColor(Color.White)
.height(50)
.width(120)
.textAlign(TextAlign.Center)
List() {
ForEach(this.table.data, (item: PeopleItem) => {
ListItem() {
Text((item as object)[this.getHeaderItemByIndex(index)?.name || ""].toString())
.fontColor(Color.White)
.width("100%")
.textAlign(TextAlign.Center)
}
.height(50)
})
}
.width(120)
}
.backgroundColor(Color.Gray)
}
changeListItemIndex(startIndex: number, toIndex: number) {
let startTarget = new headItemModel(this.table.head[startIndex]);
startTarget.index = toIndex
let toTarget = new headItemModel(this.table.head[toIndex])
toTarget.index = startIndex
this.table.head[startIndex] = startTarget;
this.table.head[toIndex] = toTarget;
this.table.head.sort((a, b) => a.index - b.index)
this.table.head = [...this.table.head]
}
build() {
Row() {
List() {
ForEach(this.table.head, (v: headItem, i: number) => {
ListItem() {
Column({ space: 20 }) {
Text(v.title)
.fontSize(25)
ForEach(this.table.data, (v2: PeopleItem, i2: number) => {
Row() {
Text((v2 as object)[v.name].toString())
}
})
}
.width('100%')
.backgroundColor(i % 2 === 1 ? '#fff67b7b' : '#ffffec69')
}
.backgroundColor('#ff87ecf5')
.width('33%')
})
}
.onItemDragStart((event: ItemDragInfo, itemIndex: number) => {
return this.getDragItemList(itemIndex)
})
.onItemDrop((event: ItemDragInfo, itemIndex: number, insertIndex: number, isSuccess: boolean) => {
if (!isSuccess || insertIndex >= this.table.head.length) {
return;
}
return this.changeListItemIndex(itemIndex, insertIndex)
})
.listDirection(Axis.Horizontal)
.width('100%')
.margin({
top: 100
})
}
.height('50%')
.width('100%')
}
}
src/main/ets/viewModels/List.ets
export interface List {
head: headItem[]
data: PeopleItem[]
}
export interface PeopleItem {
name: string
age: number
sex: "男" | "女"
}
export interface headItem {
title: string
name: string
index: number
}
export class ListModel implements List {
head: headItem[] = []
data: PeopleItem[] = []
constructor(model: List) {
this.head = model.head
this.data = model.data
}
}
export class PeopleItemModel implements PeopleItem {
name: string = ''
age: number = 0
sex: "男" | "女" = "男"
constructor(model: PeopleItem) {
this.name = model.name
this.age = model.age
this.sex = model.sex
}
}
export class headItemModel implements headItem {
title: string = ''
name: string = ''
index: number = 0
constructor(model: headItem) {
this.title = model.title
this.name = model.name
this.index = model.index
}
}