梅科尔工作室-王柯竣-鸿蒙笔记3

基础知识方面:

由list容器组件和listitem容器组件构成,list是一个大容器,listitem是大容器里的小容器

使用说明

示例

渲染控制:

ArkTS也提供了渲染控制的能力。条件渲染可根据应用的不同状态,渲染对应状态下的UI内容。循环渲染可从数据源中迭代获取数据,并在每次迭代过程中创建相应的组件。

条件渲染:

使用if/else进行条件渲染。

Column() {
  if (this.count < 0) {
    Text('count is negative').fontSize(14)
  } else if (this.count % 2 === 0) {
    Text('count is even').fontSize(14)
  } else {
    Text('count is odd').fontSize(14)
  }
}

循环渲染:

通过循环渲染(ForEach)从数组中获取数据,并为每个数据项创建相应的组件,可减少代码复杂度。

ForEach(
  arr: any[], 
  itemGenerator: (item: any, index?: number) => void,
  keyGenerator?: (item: any, index?: number) => string 
)

参数:

参数名

参数类型

必填

参数描述

arr

any[]

必须是数组,允许设置为空数组,空数组场景下将不会创建子组件。同时允许设置返回值为数组类型的函数,例如arr.slice(1, 3),设置的函数不得改变包括数组本身在内的任何状态变量,如Array.splice、Array.sort或Array.reverse这些改变原数组的函数。

itemGenerator

(item: any, index?: number) => void

生成子组件的lambda函数,为数组中的每一个数据项创建一个或多个子组件,单个子组件或子组件列表必须包括在大括号“{...}”中。

keyGenerator

(item: any, index?: number) => string

匿名函数,用于给数组中的每一个数据项生成唯一且固定的键值。当数据项在数组中的位置更改时,其键值不得更改,当数组中的数据项被新项替换时,被替换项的键值和新项的键值必须不同。键值生成器的功能是可选的,但是,为了使开发框架能够更好地识别数组更改,提高性能,建议提供。如将数组反向时,如果没有提供键值生成器,则ForEach中的所有节点都将重建。

示例:

// xxx.ets
@Entry
@Component
struct MyComponent {
  @State arr: number[] = [10, 20, 30]

  build() {
    Column({ space: 5 }) {
      Button('Reverse Array')
        .onClick(() => {
          this.arr.reverse()
        })

      ForEach(this.arr, (item: number) => {
        Text(`item value: ${item}`).fontSize(18)
        Divider().strokeWidth(2)
      }, (item: number) => item.toString())
    }
  }
}

数据懒加载

通过数据懒加载(LazyForEach)从提供的数据源中按需迭代数据,并在每次迭代过程中创建相应的组件。

LazyForEach(
  dataSource: IDataSource,             
  itemGenerator: (item: any) => void,  
  keyGenerator?: (item: any) => string 
): void

interface IDataSource {
  totalCount(): number;                                           
  getData(index: number): any;                                   
  registerDataChangeListener(listener: DataChangeListener): void;   
  unregisterDataChangeListener(listener: DataChangeListener): void;
}

interface DataChangeListener {
  onDataReloaded(): void;                      
  onDataAdd(index: number): void;            
  onDataMove(from: number, to: number): void; 
  onDataDelete(index: number): void;         
  onDataChange(index: number): void;          
}

参数名

参数类型

必填

参数描述

dataSource

IDataSource

实现IDataSource接口的对象,需要开发者实现相关接口。

itemGenerator

(item: any) => void

生成子组件的lambda函数,为数组中的每一个数据项创建一个或多个子组件,单个子组件或子组件列表必须包括在大括号“{...}”中。

keyGenerator

(item: any) => string

匿名函数,用于给数组中的每一个数据项生成唯一且固定的键值。当数据项在数组中的位置更改时,其键值不得更改,当数组中的数据项被新项替换时,被替换项的键值和新项的键值必须不同。键值生成器的功能是可选的,但是,为了使开发框架能够更好地识别数组更改,提高性能,建议提供。如将数组反向时,如果没有提供键值生成器,则LazyForEach中的所有节点都将重建。

IDataSource类型说明

DataChangeListener类型说明

名称

描述

onDataReloaded(): void

重新加载所有数据。

onDataAdded(index: number): void (deprecated)

通知组件index的位置有数据添加。

onDataMoved(from: number, to: number): void (deprecated)

通知组件数据从from的位置移到to的位置。

onDataDeleted(index: number): void (deprecated)

通知组件index的位置有数据删除。

onDataChanged(index: number): void (deprecated)

通知组件index的位置有数据变化。

onDataAdd(index: number): void 8+

通知组件index的位置有数据添加。

onDataMove(from: number, to: number): void 8+

通知组件数据从from的位置移到to的位置。

onDataDelete(index: number): void 8+

通知组件index的位置有数据删除。

onDataChange(index: number): void 8+

通知组件index的位置有数据变化。

示例:

// xxx.ets
class BasicDataSource implements IDataSource {
  private listeners: DataChangeListener[] = []

  public totalCount(): number {
    return 0
  }

  public getData(index: number): any {
    return undefined
  }

  registerDataChangeListener(listener: DataChangeListener): void {
    if (this.listeners.indexOf(listener) < 0) {
      console.info('add listener')
      this.listeners.push(listener)
    }
  }

  unregisterDataChangeListener(listener: DataChangeListener): void {
    const pos = this.listeners.indexOf(listener);
    if (pos >= 0) {
      console.info('remove listener')
      this.listeners.splice(pos, 1)
    }
  }

  notifyDataReload(): void {
    this.listeners.forEach(listener => {
      listener.onDataReloaded()
    })
  }

  notifyDataAdd(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataAdd(index)
    })
  }

  notifyDataChange(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataChange(index)
    })
  }

  notifyDataDelete(index: number): void {
    this.listeners.forEach(listener => {
      listener.onDataDelete(index)
    })
  }

  notifyDataMove(from: number, to: number): void {
    this.listeners.forEach(listener => {
      listener.onDataMove(from, to)
    })
  }
}

class MyDataSource extends BasicDataSource {
  // 初始化数据列表
  private dataArray: string[] = ['/path/image0.png', '/path/image1.png', '/path/image2.png', '/path/image3.png']

  public totalCount(): number {
    return this.dataArray.length
  }

  public getData(index: number): any {
    return this.dataArray[index]
  }

  public addData(index: number, data: string): void {
    this.dataArray.splice(index, 0, data)
    this.notifyDataAdd(index)
  }

  public pushData(data: string): void {
    this.dataArray.push(data)
    this.notifyDataAdd(this.dataArray.length - 1)
  }
}

@Entry
@Component
struct MyComponent {
  private data: MyDataSource = new MyDataSource()

  build() {
    List({ space: 3 }) {
      LazyForEach(this.data, (item: string) => {
        ListItem() {
          Row() {
            Image(item).width(50).height(50)
            Text(item).fontSize(20).margin({ left: 10 })
          }.margin({ left: 10, right: 10 })
        }
        .onClick(() => {
          // 每点击一次列表项,数据增加一项
          this.data.pushData('/path/image' + this.data.totalCount() + '.png')
        })
      }, item => item)
    }
  }
}

本次作业:

列表示例:

@Entry
@Component
struct zuoye3 {
  build() {
    Column(){
      List( ) {
        ListItem(){
          Text("示例1")
            .fontSize(30).width("100%").height("10%").backgroundColor("#DCDCDC")
        }
        ListItem(){
          Text("示例2")
            .fontSize(30).width("100%").height("10%").backgroundColor("#BABABA")
        }
        ListItem(){
          Text("示例3")
            .fontSize(30) .width("100%").height("10%").backgroundColor("#BDDB")
        }
        ListItem(){
          Text("示例4")
            .fontSize(30).width("100%").height("10%").backgroundColor("#1264")
        }
      }


    }
    .width("100%").height("100%").justifyContent(FlexAlign.Center)
  }
}

if-else-else if示例:

//import {child} from"../applicationability/child"
@Entry
@Component
struct zuoye5{
 @State fathernum : number= -1

  build(){
    Column(){
      Column(){
        if(this.fathernum%2===0){
          Text('count is negative')
            .fontSize(50)
            .fontWeight(FontWeight.Bold)
        }
        else if(this.fathernum%3===0){
          Text('even')
            .fontSize(50)
            .fontWeight(FontWeight.Bold)
        } else{
          Text('odd')
            .fontSize(50)
            .fontWeight(FontWeight.Bold)
        }
      }

    }
    .width("100%").height("100%").justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center)
  }
}

讲解:if-else组件必须在容器组件内使用。特别需要注意的一点是对于fathernum的赋值情况:其中的

number= -1不可少,因为加了number才能够确定fathernum才有类型。我做的时候犯的错误有,没加number,以及写成了:@State fathernum : number= “-1”,这里是不需要加引号的。

循环渲染示例:

@Entry
@Component
struct zuoye4 {
  private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]  // 一个列表

  build() {
    Column() {
      Column() {
        List({ space: 20 }) {
          //for循环渲染出10个Listitem小列表
          ForEach(this.arr, (item) => {
            ListItem() {
              //使列表里面的元素转化为字符串出现到文本里
              Text(item.toString())
//                设置长度
                .width('100%')
//                设置宽度
                .height(90)
//                  文字大小
                .fontSize(36)
//                  文字居中
                .textAlign(TextAlign.Center)
//                  背景颜色
                .backgroundColor("#007DEF")
//              使ListItem出现圆角
                .borderRadius(30)
            }
          })
        }
//                    排列方向
        .listDirection(Axis.Vertical)

      }
      .width("90%")
      .height('90%')
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.SpaceAround)


  }
}

这里需要注意的是:要设置排列的方向 .listDirection(Axis.Vertical)不可少

父子组件:

父组件:

import{child} from"../applicationability/child"
@Entry
@Component
struct zuoye6{
  //设fathernum为number类型值为0
  @State fathernum:number = 0
  //设fatherstatu为boolean类型值为true
  @State fatherstatu:boolean = true
  build() {
    Row() {
      Column() {
        child({ childnum: $fathernum,childnum1:$fatherstatu})
      }
      .width('100%')
    }
    .height('100%')
  }
}

子组件:

@Component
export struct child{  //导出
  @Link childnum:number
  @Link childnum1:boolean
  build() {
    Column({space:10}) {
      //布尔类型:如果真执行,如果假则不执行;真假由childnum1的值决定
      if(this.childnum1){
        //进行字符的转换
        Text(this.childnum.toString())
          .fontSize(80)
          .fontColor(Color.Red)
      }
      //设置一个按钮
      Button('增加')
        .width(200).height(90)
        .fontSize(30)
           //设置点击事件
        .onClick(()=>{
//          每点击一次,childnum+1
          this.childnum++
        })
      Button('减少')
        .width(200).height(90)
        .fontSize(30)
        .onClick(()=>{
          //点击后childnum的值减1
          this.childnum--
        })
      Button('归零')
        .width(200).height(90)
        .fontSize(30)
        .onClick(()=>{
//          点击之后归零
          this.childnum = 0
        })
      Button('显示')
        .width(200).height(90)
        .fontSize(30)
        .onClick(()=>{
          //开关设置,也就是辨别真假
          this.childnum1 =! this.childnum1
        })
    }
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值