List 是通过 LazyForEach 来实现的;通过改变 keyGenertator(LazyForEach中的参数)的返回值,来实现刷新行的效果。代码如下:
@Entry
@Component
struct ListAct {
@State baseAdapter: MyAdapter = null;
private scroller: Scroller = new Scroller();
aboutToAppear() {
this.initDatas();
}
initDatas() {
let list: ListDataItem[] = new Array<ListDataItem>(100);
for (let i = 0, end = list.length; i < end; i++) {
list[i] = new ListDataItem("条目:" + (i + 1));
}
this.baseAdapter = new MyAdapter(list);
}
addDatas(index: number, count: number) {
let list: ListDataItem[] = new Array<ListDataItem>(count);
for (let i = 0, end = count; i < end; i++) {
list[i] = new ListDataItem("新增条目:" + (i + 1));
}
this.baseAdapter.addDatas(list, index);
}
refreshAllDatas() {
let list: ListDataItem[] = new Array<ListDataItem>(20);
for (let i = 0, end = list.length; i < end; i++) {
list[i] = new ListDataItem("刷新条目:" + (i + 1));
}
this.baseAdapter.refreshDatas(list);
}
@Builder itemEnd(item: ListDataItem, index: number) {
// 侧滑后尾端出现的组件
Button({ type: ButtonType.Normal }) {
Row() {
Row() {
Image($r('app.media.app_icon'))
.width(20)
.height(20)
.objectFit(ImageFit.Contain)
.margin({ left: 16, right: 16 })
Text("修改")
}.onClick(() => {
item.name = "修改" + item.name;
// this.baseAdapter.refreshDataByIndex(index);
this.baseAdapter.refreshData(item);
})
Row() {
Image($r('app.media.app_icon'))
.width(20)
.height(20)
.objectFit(ImageFit.Contain)
.margin({ left: 16, right: 16 })
Text("删除")
}.onClick(() => {
// this.baseAdapter.removeDataByIndex(index);
this.baseAdapter.removeData(item);
})
}
}.height(40)
}
build() {
Column() {
Row() {
Button("添加数据").onClick(() => {
this.addDatas(0, 2);
})
Button("刷新数据").onClick(() => {
this.refreshAllDatas();
})
}
List({ space: 8, scroller: this.scroller }) {
LazyForEach(this.baseAdapter, (item: ListDataItem, index) => {
ListItem() {
if (item) {
Row() {
Text(item.name).margin(24)
}.width("100%").align(Alignment.Start)
}
}
.swipeAction({ end: this.itemEnd.bind(this, item, index) }) // 设置侧滑属性
}, (item: ListDataItem, index) => item.getKey())
}
.backgroundColor('#eeeeee')
.divider({ strokeWidth: 1, color: 0x222222 })
.layoutWeight(1)
}
}
}
class ListDataItem {
name: string;
private key: string = null;
constructor(name: string) {
this.name = name;
}
public clearKey() {
this.key = null;
}
public getKey() {
if (this.key == null) {
this.key = uuid();
}
return this.key;
}
}
class BaseAdapter <T> implements IDataSource {
private listeners: DataChangeListener[] = new Array<DataChangeListener>();
protected dataArray: T[];
constructor(dataArray: T[]) {
this.dataArray = dataArray ? dataArray : [];
}
public refreshDatas(dataArray: T[]) {
this.dataArray = dataArray;
this.notifyDataReload();
}
notifyDataReload(): void {
this.listeners.forEach(listener => {
listener.onDataReloaded();
})
}
registerDataChangeListener(listener: DataChangeListener): void {
if (this.listeners.indexOf(listener) < 0) {
this.listeners.push(listener);
}
}
unregisterDataChangeListener(listener: DataChangeListener): void {
const pos = this.listeners.indexOf(listener);
if (pos >= 0) {
this.listeners.splice(pos, 1);
}
}
public totalCount(): number {
return this.dataArray.length;
}
public getData(index: number): T {
return this.dataArray[index];
}
public getCount(): number {
return this.dataArray.length;
}
}
class MyAdapter extends BaseAdapter<ListDataItem> {
constructor(dataArray: ListDataItem[]) {
super(dataArray);
}
public refreshData(t: ListDataItem) {
this.refreshDataByIndex(this.dataArray.indexOf(t));
}
public refreshDataByIndex(index: number) {
if (index >= 0 && index < this.dataArray.length) {
this.dataArray[index].clearKey();
this.notifyDataReload();
}
}
public addData(t: ListDataItem, index: number = -1): void {
for (let item of this.dataArray) item.clearKey();
if (index < 0 && index >= this.dataArray.length) {
this.dataArray.push(t);
} else {
this.dataArray.splice(index, 0, t);
}
this.notifyDataReload();
}
public addDatas(ts: ListDataItem[], index: number = -1): void {
if (ts && ts.length > 0) {
for (let item of this.dataArray) item.clearKey();
if (index >= 0 && index < this.dataArray.length) {
this.dataArray.splice(index, 0, ...ts);
} else {
index = this.dataArray.length;
this.dataArray.splice(index, 0, ...ts);
}
this.notifyDataReload();
}
}
public removeData(t: ListDataItem) {
this.removeDataByIndex(this.dataArray.indexOf(t));
}
public removeDataByIndex(index: number) {
if (index >= 0 && index < this.dataArray.length) {
this.dataArray.splice(index, 1)
for (let item of this.dataArray) item.clearKey();
this.notifyDataReload();
}
}
}
function uuid(): string {
var uuidValue = "", k, randomValue;
for (k = 0; k < 32; k++) {
randomValue = Math.random() * 16 | 0;
if (k == 8 || k == 12 || k == 16 || k == 20) {
uuidValue += "-"
}
uuidValue += (k == 12 ? 4 : (k == 16 ? (randomValue & 3 | 8) : randomValue)).toString(16);
}
return uuidValue;
}