本篇内容 ArkTS的剩余状态管理基础部分及渲染控制
一、知识储备
1. @Watch状态变量变化的监听装饰器
观察到绑定的状态变量发生变化时,触发对应的回调函数 在第一次初始化的时候,@Watch装饰的函数不会被执行, 如果在@Watch装饰的函数内改变了其他的状态变量,也会引起状态变更和@Watch的执行
2. if else 条件判断
if (this.count > 29) {
this.total = this.count * 3
} else if (this.count > 12) {
this.total = this.count * 2
} else {
this.total = this.count * 1
}
3. switc 条件判断
switch (refreshStatus) {
case RefreshStatus.Inactive:
console.error('Refresh status Inactive is ' + refreshStatus)
break;
case RefreshStatus.Drag:
console.error('Refresh status Drag is ' + refreshStatus)
this.counter += 1;
break;
case RefreshStatus.OverDrag:
console.error('Refresh status OverDrag is ' + refreshStatus)
break;
case RefreshStatus.Refresh:
console.error('Refresh status Refresh is ' + refreshStatus)
break;
case RefreshStatus.Done:
console.error('Refresh status Done is ' + refreshStatus)
break;
}
4. ForEach 循环渲染
ForEach(this.foodArr, (item: string) => {
Food({ food: item })
})
5.LazyForEach
必须在容器组件内使用,仅有List/Grid/Swiper以及WaterFlow组件支持数据懒加载
LazyForEach(
dataSource: IDataSource, // 需要进行数据迭代的数据源
itemGenerator: (item: any, index: number) => void, // 子组件生成函数
keyGenerator?: (item: any, index: number) => string // 键值生成函数
): void
二、效果一览
三、源码分析讲解
@Entry
@Component
struct AppOtherPage {
@State count: number = 2;
@State isRefreshing: boolean = false
@State counter: number = 0;
@State foodArr: string[] = ['西红柿', '土豆', '苹果', '西瓜']
private dataSource: MyDataSource = new MyDataSource(); //定义数据源
aboutToAppear() {
for (let i = 0; i < 30; i++) {
this.dataSource.pushData('我是第' + i + '个')
}
}
build() {
Row() {
Column() {
Goods({ count: this.count })
Text(`页面刷新状态是:${this.isRefreshing}`)
Refresh({ refreshing: $$this.isRefreshing, offset: 120, friction: 100 }) {
Text(`正在下拉刷新第${this.counter}次`)
}
.onStateChange((refreshStatus: RefreshStatus) => {
switch (refreshStatus) {
case RefreshStatus.Inactive:
console.error('Refresh status Inactive is ' + refreshStatus)
break;
case RefreshStatus.Drag:
console.error('Refresh status Drag is ' + refreshStatus)
this.counter += 1;
break;
case RefreshStatus.OverDrag:
console.error('Refresh status OverDrag is ' + refreshStatus)
break;
case RefreshStatus.Refresh:
console.error('Refresh status Refresh is ' + refreshStatus)
break;
case RefreshStatus.Done:
console.error('Refresh status Done is ' + refreshStatus)
break;
}
})
ForEach(this.foodArr, (item: string) => {
Food({ food: item })
})
Button(`商品价格计算${this.count}`)
.onClick(() => {
this.count += 5;
})
.type(ButtonType.Capsule)
Button(`添加数据到列表尾部`)
.onClick(() => {
this.dataSource.pushData('我是尾部追加的')
})
.type(ButtonType.Capsule)
Button(`添加数据到列表第十位`)
.onClick(() => {
this.dataSource.addData(10,'我是手动添加的')
})
.type(ButtonType.Capsule)
List({ space: 3 }) {
LazyForEach(this.dataSource, (item: string) => {
ListItem() {
Row() {
Food({ food: item })
.onAppear(() => {
console.error('appear:' + item)
})
}.margin({ left: 10, right: 10, top: 10 })
}
}, (item: string) => item)
}.cachedCount(5)
.height('100%')
}
}
}
}
@Component
struct Food {
@State food: string = 'food'
build() {
Row() {
Column() {
Text(this.food)
.height('10%')
.fontSize(44)
.fontWeight(FontWeight.Bold)
}
}
}
}
@Component
struct Goods {
@Prop @Watch('calcAmount') count: number;
@State total: number = 0;
calcAmount(): void {
if (this.count > 29) {
this.total = this.count * 3
} else if (this.count > 12) {
this.total = this.count * 2
} else {
this.total = this.count * 1
}
}
build() {
Text(`商品的总价是:${this.total}`)
}
}
class BasicDataSource implements IDataSource {
private listenerArr: DataChangeListener [] = [];
protected listData: string[] = [];
public totalCount(): number {
return this.listData.length
}
public unregisterDataChangeListener(listener: DataChangeListener): void {
const pos = this.listenerArr.indexOf(listener);
if (pos > 0) {
console.info('remove listener')
this.listenerArr.splice(pos, 1)
}
}
public registerDataChangeListener(listener: DataChangeListener): void {
if (this.listenerArr.indexOf(listener) < 0) {
console.info('add listener')
this.listenerArr.push(listener)
}
}
public getData(index: number): string {
return this.listData[index];
}
notifyDataReload(): void {
this.listenerArr.forEach(listener => {
listener.onDataReloaded();
})
}
notifyDataChange(index: number): void {
this.listenerArr.forEach(listener => {
listener.onDataChange(index)
})
}
notifyDataAdd(index: number): void {
this.listenerArr.forEach(listener => {
listener.onDataAdd(index)
})
}
notifyDataDelete(index: number): void {
this.listenerArr.forEach(listener => {
listener.onDataDelete(index)
})
}
notifyDataMove(from: number, to: number): void {
this.listenerArr.forEach(listener => {
listener.onDataMove(from, to)
})
}
}
class MyDataSource extends BasicDataSource {
private dataArr: string[] = []
public totalCount(): number {
return this.dataArr.length;
}
public getData(index: number): string {
return this.dataArr[index]
}
public addData(index: number, data: string): void {
this.dataArr.splice(index, 0, data)
this.notifyDataAdd(index)
}
public pushData(data: string): void {
this.dataArr.push(data)
this.notifyDataAdd(this.dataArr.length - 1)
}
}