下面以待辦事項管理為例,介紹如何快速實現(xiàn)新增和刪除列表項功能。
(相關資料圖)
想了解更多關于開源的內(nèi)容,請訪問:
清一色開源基礎軟件社區(qū)
https://ost.51cto.com
列表的編輯模式用途十分廣泛,常見于待辦事項管理、文件管理、備忘錄的記錄管理等應用場景。在列表的編輯模式下,新增和刪除列表項是最基礎的功能,其核心是對列表項對應的數(shù)據(jù)集合進行數(shù)據(jù)添加和刪除。
下面以待辦事項管理為例,介紹如何快速實現(xiàn)新增和刪除列表項功能。
本例基于以下環(huán)境開發(fā),開發(fā)者也可以基于其他適配的版本進行開發(fā):
IDE: DevEco Studio 3.1 ReleaseSDK: Ohos_sdk_public 3.2.12.5(API Version 9 Release)如下圖所示,當用戶點擊添加按鈕時,將彈出列表項選擇界面,用戶點擊確定后,列表中新增對應項目。
圖17新增待辦
定義列表項數(shù)據(jù)結(jié)構(gòu)和初始化列表數(shù)據(jù),構(gòu)建列表整體布局和列表項。以待辦事項管理為例,首先定義待辦事項的數(shù)據(jù)結(jié)構(gòu):
import util from "@ohos.util";export class ToDo { key: string = util.generateRandomUUID(true); name: string; constructor(name: string) { this.name = name; }}
然后,初始化待辦事項列表和可選事項列表:
@State toDoData: ToDo[] = [];private availableThings: string[] = ["讀書", "運動", "旅游", "聽音樂", "看電影", "唱歌"];
構(gòu)建UI界面。初始界面包含“待辦”和新增按鈕“+”:
Text("待辦") .fontSize(36) .margin({ left: 40})Blank()Text("+") .fontWeight(FontWeight.Lighter) .fontSize(40) .margin({ right: 30 })
構(gòu)建列表布局并通過ForEach循環(huán)渲染列表項:
List({ space: 10 }) { ForEach(this.toDoData, (toDoItem) => { ListItem() { ... } }, toDoItem => toDoItem.key)}
為新增按鈕綁定點擊事件,并在事件中通過TextPickerDialog.show添加新增列表項的邏輯:
Text("+") .onClick(() => { TextPickerDialog.show({ range: this.availableThings, // 將可選事項列表配置到選擇對話框中 onAccept: (value: TextPickerResult) => { this.toDoData.push(new ToDo(this.availableThings[value.index])); // 用戶點擊確認,將選擇的數(shù)據(jù)添加到待辦列表toDoData中 }, }) })
如下圖所示,當用戶長按列表項進入刪除模式時,提供用戶刪除列表項選擇的交互界面,用戶勾選完成后點擊刪除按鈕,列表中刪除對應的項目。
圖18長按刪除待辦事項
列表的刪除功能一般進入編輯模式后才可使用,所以需要提供編輯模式的入口。以待辦列表為例,通過LongPressGesture()監(jiān)聽列表項的長按事件,當用戶長按列表項時,進入編輯模式。
// ToDoListItem.etsFlex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) { ...}.gesture(GestureGroup(GestureMode.Exclusive, LongPressGesture() // 監(jiān)聽長按事件 .onAction(() => { if (!this.isEditMode) { this.isEditMode = true; //進入編輯模式 this.selectedItems.push(this.toDoItem); // 記錄長按時選中的列表項 } }) ))
需要響應用戶的選擇交互,記錄要刪除的列表項數(shù)據(jù)。在待辦列表中,通過勾選框的勾選或取消勾選,響應用戶勾選列表項變化,記錄所有選擇的列表項。
// ToDoListItem.etsif (this.isEditMode) { Checkbox() .onChange((isSelected) => { if (isSelected) { this.selectedItems.push(this.toDoItem) // 勾選時,記錄選中的列表項 } else { let index = this.selectedItems.indexOf(this.toDoItem) if (index !== -1) { this.selectedItems.splice(index, 1) // 取消勾選時,則將此項從selectedItems中刪除 } } }) ...}
需要響應用戶點擊刪除按鈕事件,刪除列表中對應的選項。
// ToDoList.etsButton("刪除") .onClick(() => { // 刪除選中的列表項對應的toDoData數(shù)據(jù) let leftData = this.toDoData.filter((item) => { return this.selectedItems.find((selectedItem) => selectedItem !== item); }) this.toDoData = leftData; this.isEditMode = false; }) ...
新增和刪除列表項的實現(xiàn)共涉及三個文件,各文件完整代碼如下:
待辦事項數(shù)據(jù)結(jié)構(gòu)代碼(ToDo.ets):
// ToDo.etsimport util from "@ohos.util";export class ToDo { key: string = util.generateRandomUUID(true) name: string; constructor(name: string) { this.name = name; }}
待辦事項列表代碼(ToDoList.ets):
// ToDoList.etsimport { ToDo } from "../model/ToDo";import { ToDoListItem } from "./ToDoListItem";@Entry@Componentstruct ToDoList { @State toDoData: ToDo[] = [] @Watch("onEditModeChange") @State isEditMode: boolean = false @State selectedItems: ToDo[] = [] private availableThings: string[] = ["讀書", "運動", "旅游", "聽音樂", "看電影", "唱歌"] saveData(value: string) { this.toDoData.push(new ToDo(value)) } onEditModeChange() { if (!this.isEditMode) { this.selectedItems = [] } } build() { Column() { Row() { if (this.isEditMode) { Text("X") .fontSize(20) .onClick(() => { this.isEditMode = false; }) .margin({ left: 20, right: 20 }) Text("已選擇" + this.selectedItems.length + "項") .fontSize(24) } else { Text("待辦") .fontSize(36) .margin({ left: 40}) Blank() Text("+") .fontWeight(FontWeight.Lighter) .fontSize(40) .margin({ right: 30 }) .onClick(() => { TextPickerDialog.show({ range: this.availableThings, onAccept: (value: TextPickerResult) => { this.toDoData.push(new ToDo(this.availableThings[value.index])) console.info("to do data: " + JSON.stringify(this.toDoData)) }, }) }) } } .height("12%") .width("100%") List({ initialIndex: 0, space: 10 }) { ForEach(this.toDoData, toDoItem => { ListItem() { ToDoListItem({ isEditMode: $isEditMode, toDoItem: toDoItem, selectedItems: $selectedItems }) }.padding({ left: 24, right: 24, bottom: 12 }) }, toDoItem => toDoItem.key) } .height("73%") .listDirection(Axis.Vertical) .edgeEffect(EdgeEffect.Spring) if (this.isEditMode) { Row() { Button("刪除") .width("80%") .onClick(() => { let leftData = this.toDoData.filter((item) => { return this.selectedItems.find((selectedItem) => selectedItem != item) }) console.log("leftData: " + leftData); this.isEditMode = false; this.toDoData = leftData; }) .backgroundColor("#ffd75d5d") } .height("15%") } } .backgroundColor("#fff1f3f5") .width("100%") .height("100%") }}
待辦事項代碼(ToDoListItem.ets):
// ToDoListItem.etsimport { ToDo } from "../model/ToDo";@Componentexport struct ToDoListItem { @Link isEditMode: boolean @Link selectedItems: ToDo[] private toDoItem: ToDo; hasBeenSelected(): boolean { return this.selectedItems.indexOf(this.toDoItem) != -1 } build() { Flex({ justifyContent: FlexAlign.SpaceBetween, alignItems: ItemAlign.Center }) { Row({ space: 4 }) { Circle() .width(24) .height(24) .fill(Color.White) .borderWidth(3) .borderRadius(30) .borderColor("#ffdcdfdf") .margin({ right: 10 }) Text(`${this.toDoItem.name}`) .maxLines(1) .fontSize(24) .textOverflow({ overflow: TextOverflow.Ellipsis }) } .padding({ left: 12 }) if (this.isEditMode) { Checkbox() .select(this.hasBeenSelected() ? true : false) .onChange((isSelected) => { if (isSelected) { this.selectedItems.push(this.toDoItem) } else { let index = this.selectedItems.indexOf(this.toDoItem) if (index != -1) { this.selectedItems.splice(index, 1) } } }) .width(24) .height(24) } } .width("100%") .height(80) .padding({ left: 16, right: 12, top: 4, bottom: 4 }) .borderRadius(24) .linearGradient({ direction: GradientDirection.Right, colors: this.hasBeenSelected() ? [[0xffcdae, 0.0], [0xFfece2, 1.0]] : [[0xffffff, 0.0], [0xffffff, 1.0]] }) .gesture( GestureGroup(GestureMode.Exclusive, LongPressGesture() .onAction(() => { if (!this.isEditMode) { this.isEditMode = true this.selectedItems.push(this.toDoItem) } }) ) ) }}
想了解更多關于開源的內(nèi)容,請訪問:
清一色開源基礎軟件社區(qū)
https://ost.51cto.com
關鍵詞: