1# 如何实现列表项ListItem滑动显示快捷菜单 2 3## 场景说明 4 5在使用列表List的应用中,可以滑动列表项ListItem显示快捷菜单,快速完成对列表项的操作。List垂直布局时滑动操作支持左滑和右滑。 6 7## 效果呈现 8 9本示例最终效果如下: 10 11 12 13## 运行环境 14本例基于以下环境开发,开发者也可以基于其他适配的版本进行开发: 15- IDE: DevEco Studio 4.0 Release 16- SDK: Ohos_sdk_public 4.0.10.13 (API Version 10 Release) 17## 实现原理 18本例关键功能点及其实现思路如下: 191. 自定义组件实现划出后的快捷菜单。 20 212. 利用ListItem组件的swipeAction属性,设置ListItem的划出组件为上述自定义组件。 22 23## 开发步骤 24 251. 实现自定义组件。本示例使用Row、Image组件组装一个包含两个图标按钮的快捷菜单组件。在定义组件时,给定入参便于后续定位到被滑动的ListItem。本示例中,当滑动出菜单后,点击置顶按钮可以将当前ListItem置顶,点击删除按钮可以删除当前ListItem。 26 27 ```ts 28 @Builder itemEnd(index:number){ 29 Row(){ 30 Image($r("app.media.ic_public_topping")) 31 ... 32 .onClick(()=>{ 33 this.itemIndexArr.unshift(this.itemIndexArr.splice(index,1)[0]) 34 }) 35 Image($r("app.media.ic_public_delete")) 36 ... 37 .onClick(()=>{ 38 this.itemIndexArr.splice(index,1) 39 }) 40 }.padding(4) 41 .justifyContent(FlexAlign.SpaceEvenly) 42 } 43 ``` 44 452. 使用ForEach循环渲染列表,并为ListItem设置swipeAction属性为上述自定义组件,设置属性时绑定入参。 46 47 swipeAction支持设置不同的滑动方向: 48 49 * start:List垂直布局时,向右滑动ListItem时在左侧显示的组件。本示例中未配置。 50 51 * end:List垂直布局时,向左滑动ListItem时在右侧显示的组件。 52 53 ```ts 54 ForEach(this.itemIndexArr,(item:string,index) =>{ 55 ListItem(){ 56 Text('' + item) 57 ... 58 }.swipeAction({ end:this.itemEnd(index), edgeEffect: SwipeEdgeEffect.Spring}) 59 },(item:string)=>item) 60 ``` 61 62## 完整代码 63 64通过上述步骤可以完成整个示例的开发,完整代码如下: 65 66```ts 67@Entry 68@Component 69struct Index { 70 @State itemIndexArr:Array<number> = [1,2]; 71 @Builder itemEnd(index:number){ 72 Row(){ 73 Image($r("app.media.ic_public_topping")) 74 .width(32) 75 .height(32) 76 .margin(4) 77 .onClick(()=>{ 78 this.itemIndexArr.unshift(this.itemIndexArr.splice(index,1)[0]) 79 }) 80 Image($r("app.media.ic_public_delete")) 81 .width(32) 82 .height(32) 83 .margin(4) 84 .onClick(()=>{ 85 this.itemIndexArr.splice(index,1) 86 }) 87 }.padding(4) 88 .justifyContent(FlexAlign.SpaceEvenly) 89 } 90 91 build() { 92 Column() { 93 List({ space: 10 }) { 94 ForEach(this.itemIndexArr, (item: string, index) => { 95 ListItem() { 96 Text('' + item) 97 .width('100%') 98 .height(100) 99 .fontSize(16) 100 .margin({ top: 10 }) 101 .borderRadius(16) 102 .textAlign(TextAlign.Center) 103 .backgroundColor(Color.White) 104 }.swipeAction({ end: this.itemEnd(index), edgeEffect: SwipeEdgeEffect.Spring }) 105 }, (item: string) => item) 106 }.height('90%') 107 108 Row() { 109 Image($r("app.media.ic_public_add_norm")) 110 .width(40) 111 .height(40) 112 .margin(4) 113 .onClick(() => { 114 if (this.itemIndexArr.length === 0) { 115 this.itemIndexArr.push(1) 116 } else { 117 this.itemIndexArr.push(this.itemIndexArr[this.itemIndexArr.length-1] + 1) 118 } 119 }) 120 }.height('10%') 121 }.padding(10) 122 .backgroundColor(0xDCDCDC) 123 .width('100%') 124 .height('100%') 125 } 126} 127```