1# 如何实现列表项ListItem滑动显示快捷菜单
2
3## 场景说明
4
5在使用列表List的应用中,可以滑动列表项ListItem显示快捷菜单,快速完成对列表项的操作。List垂直布局时滑动操作支持左滑和右滑。
6
7## 效果呈现
8
9本示例最终效果如下:
10
11![listitem-slide](figures/listitem-slide-demo.gif)
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```