【鸿蒙】HarmonyOS NEXT星河入门到实战5-基础语法

目录

一、字符串拼接

1.1 常规字符串拼接

1.2 模板字符串`hello`(符号在键盘的tab上面)

二、类型转换 (数字和字符串)

2.1 字符串转数字

 2.2 数字转字符串

三、交互

3.1 点击事件

3.2 状态管理

 3.3 计数器案例

四、运算符

4.1 算数运算符

 4.2 赋值运算符

4.3 点赞案例  ​编辑

4.4 一元运算符

4.5 比较运算符

4.6 逻辑运算符

4.7 运算符的优先级

4.8 综合案例-美团购物车

五、数组与语句

5.1 数组的操作

5.1.1 查找与修改 

5.1.2 增加数组元素 

5.1.3 删除数组元素 

5.1.4 任意位置添加/删除数组元素 

5.1.5 小结 

5.2 语句 

5.2.1 if分支语句 

5.2.1.1 单分支语句

5.2.1.2 双分支语句

 5.2.1.3 小结

5.2.1.4 案例-购物车数字框

5.2.1.5 if-多分支

 5.2.2 switch -分支语句

5.2.3 三元条件表达式

5.2.4 条件渲染

5.2.5 条件渲染案例-京东加购

5.2.6 循环语句

5.2.6.1 while-语句

5.2.6.2 for循环语句

5.2.6.3 退出循环 -break-continue

5.2.6.4 遍历数组

5.2.6.4.1 使用for遍历 数组​编辑

5.2.6.4.2 使用for...of 遍历数组 

5.2.6.4.3 案例

5.2.7 对象数组

5.2.8 ForEach渲染控制

5.2.8.1 ForEach渲染控制

5.2.8.2 FofEach案例 -新闻列表

 六、渲染控制综合案例

6.1 生肖抽卡-初始布局-Badge角标组件

6.2 生肖抽卡 - 初始布局-Grid布局

6.3 生肖抽卡 - 数据动态渲染

6.4 生肖抽卡 - 遮罩和显隐动画

6.4.1 抽卡遮罩层

6.4.2 生肖抽卡 -显隐效果控制

6.4.3 生肖抽卡 -随机卡片

6.4.4 生肖抽奖 - 抽大奖

6.4.4.1 抽大奖遮罩层

6.4.4.2 抽大奖显隐控制

6.4.5 生肖抽卡- 随机抽卡&再来一次


前言:学习数据类型、控制语句等

一、字符串拼接

1.1 常规字符串拼接

import window from '@ohos.window';
let name: string = '春天的菠菜'
let age: number = 18
console.log('简介信息:','姓名' + name)
console.log('简介信息:','年龄' + age)

let num1: number = 120
let num2: number = 320
console.log('总数:',num1 + num2)
@Entry
@Component
struct Index {
  @State message: string = '春天的菠菜';


  onPageShow(): void {
    window.getLastWindow(AppStorage.get("context"), (err, data) => {
      if (err.code) {
        console.error('Failed to get last window. Cause:' + JSON.stringify(err));
        return;
      }
      data.setFullScreen(true)
    });
  }
  build() {
    Row(){
      Column(){
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
      }
      .width('100%')
    }
    .height('100%')

  }
}

1.2 模板字符串`hello`(符号在键盘的tab上面)

import window from '@ohos.window';
let name: string = `春天的菠菜`  // 注意这里的符号是 · · tab键盘上面的
let age: number = 18
console.log('简介信息:',`姓名:${name},年龄:${age}`) // 注意这里的符号是 · · tab键盘上面的

@Entry
@Component
struct Index {
  @State message: string = '春天的菠菜';


  onPageShow(): void {
    window.getLastWindow(AppStorage.get("context"), (err, data) => {
      if (err.code) {
        console.error('Failed to get last window. Cause:' + JSON.stringify(err));
        return;
      }
      data.setFullScreen(true)
    });
  }
  build() {
    Row(){
      Column(){
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
      }
      .width('100%')
    }
    .height('100%')

  }
}

二、类型转换 (数字和字符串)

2.1 字符串转数字

 

 2.2 数字转字符串

import window from '@ohos.window';
let money: number = 1000.5

@Entry
@Component
struct Index {
  @State message: string = '春天的菠菜';


  onPageShow(): void {
    window.getLastWindow(AppStorage.get("context"), (err, data) => {
      if (err.code) {
        console.error('Failed to get last window. Cause:' + JSON.stringify(err));
        return;
      }
      data.setFullScreen(true)
    });
  }
  build() {
    Row(){
      Column(){
        Text(money.toString())
        Text(money.toFixed())
    
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
      }
      .width('100%')
    }
    .height('100%')

  }
}

三、交互

3.1 点击事件

import window from '@ohos.window';


@Entry
@Component
struct Index {
  @State message: string = '春天的菠菜';


  onPageShow(): void {
    window.getLastWindow(AppStorage.get("context"), (err, data) => {
      if (err.code) {
        console.error('Failed to get last window. Cause:' + JSON.stringify(err));
        return;
      }
      data.setFullScreen(true)
    });
  }
  build() {
    Row(){
      Column(){

        Button('点我,显示对话框')
          .onClick(() =>{
            console.log('你好,这是点击事件')
            AlertDialog.show({
              message: '你好这是一个弹框'
            })
          })
      }
      .width('100%')
    }
    .height('100%')

  }
}

3.2 状态管理

//  1、普通变量只会在初始化时渲染,后续变化,也不会改变
// 2、 状态变量,被装饰器修饰,会自动引起界面的刷新
import window from '@ohos.window';
//  1、普通变量只会在初始化时渲染,后续变化,也不会改变
// 2、 状态变量,被装饰器修饰,会自动引起界面的刷新

// 组件外的普通变量
let myName: string = '春天的菠菜'
@Entry
@Component

struct Index {
  // 组件内的普通变量
  myAge: number = 18

  // 组件内的状态变量
  @State myMessage: string = '点我看我 春天的菠菜七十二变'

  onPageShow(): void {
    window.getLastWindow(AppStorage.get("context"), (err, data) => {
      if (err.code) {
        console.error('Failed to get last window. Cause:' + JSON.stringify(err));
        return;
      }
      data.setFullScreen(true)
    });
  }
  build() {
    Column(){
      Text(myName)
      Text(this.myAge.toString())   // 组件内的普通变量调用需要使用this
      Text(this.myMessage).onClick(() => {
        this.myMessage = '我是猴哥'
      }
      )
    }

  }
}

 3.3 计数器案例

import window from '@ohos.window';

@Entry
@Component

struct Index {

  @State count: number = 1

  onPageShow(): void {
    window.getLastWindow(AppStorage.get("context"), (err, data) => {
      if (err.code) {
        console.error('Failed to get last window. Cause:' + JSON.stringify(err));
        return;
      }
      data.setFullScreen(true)
    });
  }
  build() {
    Row(){
      Button('-').onClick(() =>{
        this.count  = this.count - 1
      })
      Text(this.count.toString()).margin(10)
      Button('+').onClick(() =>{
        this.count  = this.count + 1
      })

      }
      .padding(20)



  }
}

四、运算符

4.1 算数运算符

 4.2 赋值运算符

 

注意

4.3 点赞案例  

import window from '@ohos.window';

@Entry
@Component

struct Index {
  //  声明状态

  @State myColor: string = '#7e7e7e'

  @State count: number = 8888

  onPageShow(): void {
    window.getLastWindow(AppStorage.get("context"), (err, data) => {
      if (err.code) {
        console.error('Failed to get last window. Cause:' + JSON.stringify(err));
        return;
      }
      data.setFullScreen(true)
    });
  }
  build() {
    Column(){
      Column({space: 8}){
        Image($r('app.media.eyes'))
          .width('100%')
          .borderRadius({topLeft: 6, topRight: 6 })

        Text('考眼力又来你能看到几只鸭子?')
          .fontSize(14)
          .lineHeight(18)
          .padding({left: 5, right: 5})
        Row(){
          Text(){
            ImageSpan($r('app.media.avatar'))
              .width(16)
              .margin({right: 3})
            Span('视野联行眼镜')
              .fontSize(12)
              .fontColor('#7e7e7e')
          }
          Row(){
            Image($r('app.media.ic_love'))
              .margin({right: 3})
              .width(14)
              .fillColor(this.myColor)
            Text(this.count.toString())
              .fontSize(12)
              .fontColor(this.myColor)
          }
          .onClick(() => {
            // 修改数字
            this.count += 1
          //   修改验收
            this.myColor = '#ff0000'

          })

          }
        .width('100%')
        .justifyContent(FlexAlign.SpaceBetween)
        .padding({left: 5, right: 5})


      }
      .width('50%')
    }
    .padding(20)
  }
}

4.4 一元运算符

4.5 比较运算符

4.6 逻辑运算符

4.7 运算符的优先级

注意 !在一元,优先级高

4.8 综合案例-美团购物车

import window from '@ohos.window';

@Entry
@Component

struct Index {
  //  声明状态

  @State oldPrice: number = 40.4
  @State newPrice: number = 20.4
  @State count: number = 1

  onPageShow(): void {
    window.getLastWindow(AppStorage.get("context"), (err, data) => {
      if (err.code) {
        console.error('Failed to get last window. Cause:' + JSON.stringify(err));
        return;
      }
      data.setFullScreen(true)
    });
  }
  build() {
    Column() {
      Column() {
        // 产品
        Row({ space: 10}){
          // 图片
          Image($r('app.media.product1'))
            .width(100)
            .borderRadius(8)
          // 文字
          Column({space: 10}) {
            Column({ space: 6}) {
              Text('冲销量1000ml缤纷八果水果捞')
                .lineHeight(20)
                .fontSize(14)
              Text('含1份折扣商品')
                .fontSize(12)
                .fontColor('#7f7f7f')
            }
            .width('100%')
            .alignItems(HorizontalAlign.Start)
            Row(){
              // 价格
              Row({ space: 5}) {
                Text() {
                  Span('¥')
                    .fontSize(14)
                  Span(this.newPrice.toString())
                    .fontSize(18)
                }
                .fontColor('#ff4000')
                Text() {
                  Span('¥')
                  Span(this.oldPrice.toString())
                }
                .fontSize(14)
                .fontColor('#999')
                .decoration({type: TextDecorationType.LineThrough, color: '#999'})
              }
              // 加减
              Row() {
                Text('-')
                  .width(22)
                  .height(22)
                  .border({width:1, color: '#e1e1e1', radius: {topLeft: 5, bottomLeft: 5}})
                  .textAlign(TextAlign.Center)
                  .fontWeight(700)
                  .onClick( () =>{
                    this.count -= 1
                  })
                Text(this.count.toString())
                  .height(22)
                  .border({width: { top:1, bottom: 1 }, color: '#e1e1e1'})
                  .padding({left: 10, right: 10})
                  .fontSize(14)
                Text('+')
                  .width(22)
                  .height(22)
                  .border({width:1, color: '#e1e1e1', radius: {topRight: 5, bottomRight: 5}})
                  .textAlign(TextAlign.Center)
                  .fontWeight(700)
                  .onClick( () => {
                    this.count += 1
                  })
              }
            }
            .width('100%')
            .justifyContent(FlexAlign.SpaceBetween)
          }
          .height(75)
          .layoutWeight(1)
          .justifyContent(FlexAlign.SpaceBetween)
        }
        .width('100%')
        .alignItems(VerticalAlign.Top)
        .padding(20)

        // 结算
        Row({ space: 10 }){
          // 价格
          Column({space: 5}) {
            Text() {
              Span(`已选 ${this.count.toString()} 件,`) // 注意使用tab上面的符号
                .fontColor('#848484')
              Span('合计:')
              Span('¥')
                .fontColor('#fd4104')
              Span((this.newPrice * this.count).toFixed(2))
                .fontColor('#fd4104')
                .fontSize(16)
            }
            .fontSize(14)
            Text(`共减¥${((this.oldPrice - this.newPrice) * this.count).toFixed(2)}`)  //注意符号是tab上面的
              .fontColor('#fd4104')
              .fontSize(12)
          }
          .alignItems(HorizontalAlign.End)
          // 结算按钮
          Button('结算外卖')
            .width(110)
            .height(40)
            .backgroundColor('#fed70e')
            .fontColor('#564200')
            .fontSize(16)
            .fontWeight(600)
        }
        .width('100%')
        .height(70)
        .backgroundColor('#fff')
        .position({x:0, y: '100%'})
        .translate({y: '-100%'})
        .padding({ left: 20, right: 20 })
        .justifyContent(FlexAlign.End)
      }
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#f3f3f3')
  }
}

五、数组与语句

5.1 数组的操作

5.1.1 查找与修改 

5.1.2 增加数组元素 

 

5.1.3 删除数组元素 

5.1.4 任意位置添加/删除数组元素 

5.1.5 小结 

 

5.2 语句 

5.2.1 if分支语句 

5.2.1.1 单分支语句

5.2.1.2 双分支语句

 

 5.2.1.3 小结

 

 

5.2.1.4 案例-购物车数字框


import window from '@ohos.window';

@Entry
@Component

struct Index {

  @State count: number = 1

  onPageShow(): void {
    window.getLastWindow(AppStorage.get("context"), (err, data) => {
      if (err.code) {
        console.error('Failed to get last window. Cause:' + JSON.stringify(err));
        return;
      }
      data.setFullScreen(true)
    });
  }
  build() {
    Row(){
      Button('-').onClick(() =>{
        if(this.count >= 1){
          this.count--
        }else {
          AlertDialog.show({
            message: '不能再减了!'
          })
        }

      })
      Text(this.count.toString()).margin(10)
      Button('+').onClick(() =>{
        this.count++
      })

    }
    .padding(20)



  }
}

5.2.1.5 if-多分支

 5.2.2 switch -分支语句

5.2.3 三元条件表达式

5.2.4 条件渲染

import window from '@ohos.window';
@Entry
@Component

struct Index {
  @State age: number = 13
  onPageShow(): void {
    window.getLastWindow(AppStorage.get("context"), (err, data) => {
      if (err.code) {
        console.error('Failed to get last window. Cause:' + JSON.stringify(err));
        return;
      }
      data.setFullScreen(true)
    });
  }
  build() {
    Column(){
      if(this.age < 18){
        Text('未成年')
      }else if(this.age >= 18 && this.age <= 60){
        Text('成年人18-60')
      }else{
        Text('老年人')
      }
      Button('长大').onClick( () => {
        this.age += 5
      })
        .margin({top: 5})
      Text(`当前年龄:${this.age}`).margin({top: 5})

    }
    .width('100%')
    .padding(20)
    .backgroundColor(Color.Pink)

  }
}

 

5.2.5 条件渲染案例-京东加购

import window from '@ohos.window';
@Entry
@Component

struct Index {
  @State count: number = 2 //无库存
  onPageShow(): void {
    window.getLastWindow(AppStorage.get("context"), (err, data) => {
      if (err.code) {
        console.error('Failed to get last window. Cause:' + JSON.stringify(err));
        return;
      }
      data.setFullScreen(true)
    });
  }
  build() {
    Column() {
      Column() {
        // 底部菜单
        Row({space: 10}) {
          // 左侧菜单
          Row() {
            Column({space: 5}) {
              Image($r('app.media.ic_dianpu'))
                .width(20)
              Text('店铺')
                .fontSize(10)
                .fontColor('#262626')
            }
            Column({space: 5}) {
              Image($r('app.media.ic_kefu'))
                .width(20)
                .fillColor('#666')
              Text('客服')
                .fontSize(10)
                .fontColor('#262626')
            }
            Column({space: 5}) {
              Image($r('app.media.ic_cart2'))
                .width(20)
                .fillColor('#666')
              Text('购物车')
                .fontSize(10)
                .fontColor('#262626')
            }
          }
          .layoutWeight(1)
          .justifyContent(FlexAlign.SpaceBetween)

          if(this.count > 0){
            // 右侧按钮 -- 可以购买
            Row({space: 5}) {
              Button('加入购物车')
                .width(105)
                .height(40)
                .backgroundColor('#ffcc00')
                .fontSize(14)
                .fontWeight(600)
              Button('立即购买')
                .width(105)
                .height(40)
                .backgroundColor('#f92c1b')
                .fontSize(14)
                .fontWeight(600)
            }
          }else{
            // 右侧按钮 -- 不能购买
            Row() {
              Button('查看类似商品')
                .width(170)
                .height(40)
                .backgroundColor('#ffcc00')
                .fontSize(14)
                .fontWeight(600)
            }
          }
        }
        .width('100%')
        .height(60)
        .backgroundColor('#f7f7f7')
        .padding({left: 20, right: 10})

        if(this.count <= 0){
          // 消息提示:库存 <= 0 显示,否则隐藏
          Row() {
            // 左侧
            Row({ space: 5 }){
              Image($r('app.media.ic_lingdang'))
                .width(12)
                .fillColor('#de6a1c')
              Text('该商品暂时没有库存,看看相似商品吧')
                .fontSize(10)
                .fontColor('#de6a1c')
            }
            // 右侧
            Image($r('app.media.ic_shangjiantou'))
              .width(15)
              .padding(3)
              .fillColor('#d0662c')
              .backgroundColor('rgba(0,0,0,0.1)')
              .borderRadius(8)
          }
          .width('100%')
          .height(36)
          .backgroundColor('#fbf9da')
          .position({x: 0, y: '-36'})
          .padding({left: 20, right: 20})
          .justifyContent(FlexAlign.SpaceBetween)

        }



      }
      .position({x:0,y:'100%'})
      .translate({y: '-100%'})
    }
    .width('100%')
    .height('100%')
    .padding({bottom:20})
    .backgroundColor('#f2f2f2')

  }
}

5.2.6 循环语句

5.2.6.1 while-语句

 

 

// while循环: 可以重复的执行一段代码
// while (条件) {
//   需要循环执行的语句
// }

// 死循环: 没有结束条件
// while (true) {
//   console.log('while', '重复执行的代码')
// }

// 实际开发真正需要的, 有次数的循环
// 三要素: 变量初始值; 判断条件; 变化量(变量要变)
// let i: number = 1
// while (i < 10) {
//   console.log('小于10成立', '执行代码', i) // 9
//   i++ // 10
// }

// 需求1: 打印1-100的数字,  1, 2, 3, 4, 5 ... 100
// 三要素: 变量起始值; 判断条件; 变化量;
// let i: number = 1
// while (i <= 100) {
//   console.log('i的值:', i)
//   i++
// }

// let i: number = 100
// while (i >= 1) {
//   console.log('i的值:', i)
//   i--
// }

// 需求2: 打印 1-100 中的偶数
// let i: number = 1
// while (i <= 100) {
//   if (i % 2 === 0) {
//     console.log('i的值:', i)
//   }
//   i++
// }

// 需求3: 计算 1-10 的数字的 累加和,  1 + 2 + 3 + 4 + 5 ... + 10
// 三要素: 变量起始值; 判断条件; 变化量;
let i: number = 1
let sum: number = 0 // 存储累加的结果

while (i <= 10) {
  console.log('需要累加的数字:', i)
  // 每次执行下面这行代码, 就会进行一次累加, 并且更新累加的结果
  sum = sum + i
  i++
}
console.log('累加结果:', sum)


@Entry
@Component
struct Index {
  @State num:number = 1
  build() {
    
  }
}
5.2.6.2 for循环语句

 

 

// for (初始值; 循环条件; 变化量) {
//   重复执行的代码(循环体)
// }

// 需求: 打印 1-10 →  从 1 开始, 循环到 10 结束
// for (let i: number = 1; i <= 10; i++) {
//   console.log('for循环', i)
// }


// 1-10的和, 从1开始,循环到10
let sum = 0
for (let i: number = 1; i <= 10; i++) {
  console.log('for', i)
  sum = sum + i // sum += i
}
console.log('求和', sum)


@Entry
@Component
struct Index {
  build() {

  }
}
5.2.6.3 退出循环 -break-continue

// 退出循环:
// 1. break: 终止整个循环 (后面的循环不执行了)
// 2. continue: 退出当前这一次循环, 继续执行下一次循环 (包子当前这个不吃了, 吃下一个)

// 1. 一共8个包子, 吃到第5个, 饱了
// for (let i: number = 1; i <= 8; i++) {
//   if (i == 5) {
//     console.log('拿起了第5个包子, 发现吃不动了')
//     // 终止当前的循环 (本次循环后面的代码不执行了, 且后续循环的代码也不执行了, 跳出循环)
//     break
//   }
//   console.log('吃包子:', `第${i}个`)
// }
//
// console.log('这是循环外的代码')


// 2. 一个8个包子, 吃到第5个, 坏了
for (let i: number = 1; i <= 8; i++) {
  if (i == 5) {
    console.log('拿起了第5个包子, 发现坏了')
    // 当前这次循环不继续执行了, 继续执行下一次循环
    continue
  }
  console.log('吃包子:', `第${i}个`)
}

console.log('这是循环外的代码')


@Entry
@Component
struct Index {
  build() {

  }
}

5.2.6.4 遍历数组
5.2.6.4.1 使用for遍历 数组
5.2.6.4.2 使用for...of 遍历数组 

 

 

// 遍历数组: 利用循环, 依次按顺序访问数组的每一项
let names: string[] = ['大强', '老莫', '小龙', '大黑', '小黄']

// 数组的最后一项 names[names.length - 1]
// for (let i: number = 0; i < names.length; i++) {
//   console.log('名字是', names[i])
// }

for (let item of names) {
  console.log('数组中的每一项', item)
}


@Entry
@Component
struct Index {
  build() {

  }
}
5.2.6.4.3 案例

// 需求1: 求出下列数组元素的 累加和
// [22, 3, 44, 55, 80]
// let sum: number = 0
// let arr: number[] = [22, 3, 44, 55, 80]
//
// for (let item of arr) {
//   // console.log('每一项', item)
//   sum = sum + item
// }
// console.log('结果', sum)


// 需求2:筛选 数组中 大于等于10 的 元素,收集到一个新数组中
// [22, 3, 44, 55, 80, 10, 11, 5, -1]
// let arr: number[] = [22, 3, 44, 55, 80, 10, 11, 5, -1]
// let newArr: number[] = []
//
// // 遍历arr, 符合条件, push到newArr里面去
// for (let item of arr) {
//   if (item >= 10) {
//     newArr.push(item)
//   }
// }
// console.log('新数组', newArr)



// 需求3:数组去0,将数组中 不是0 的项收集到一个新数组中
// [22, 3, 0, 55, 0, 0, 11, 5, 0]
let arr: number[] = [22, 3, 0, 55, 0, 0, 11, 5, 0]
let newArr: number[] = []

for (let num of arr) {
  if (num != 0) {
    newArr.push(num)
  }
}
console.log('新数组', newArr)


@Entry
@Component
struct Index {
  build() {

  }
}

5.2.7 对象数组

// 对象数组 => 数组中包裹存储了很多的对象
// 1. 约定接口 (对象的类型)
interface Student {
  stuId: number
  name: string
  gender: string
  age: number
}

// 2. 基于接口, 构建对象数组
let stuArr: Student[] = [
  { stuId: 1, name: '小丽', gender: '女', age: 12 },
  { stuId: 2, name: '小红', gender: '女', age: 11 },
  { stuId: 3, name: '大强', gender: '男', age: 12 },
  { stuId: 4, name: '阿明', gender: '男', age: 13 },
]
// 包括对象的复杂数据,如果想要在日志中打印, 需要调用一个方法, 转成字符串格式
// JSON.stringify(复杂类型)  对象/数组
// console.log('学生数组', JSON.stringify(stuArr))

// 3. 具体使用 (访问 →  通过下标)
// console.log('小红', stuArr[1].name)
// console.log('小红', JSON.stringify(stuArr[1]))

// 4. 也支持遍历 for... of, 普通for
for (let item of stuArr) {
  console.log('每一项', JSON.stringify(item))
}


@Entry
@Component
struct Index {
  build() {

  }
}

5.2.8 ForEach渲染控制

5.2.8.1 ForEach渲染控制


 

import window from '@ohos.window';
@Entry
@Component

struct Index {
  @State titles:string[] = [
    '电子产品',
    '精品服饰',
    '母婴产品',
    '影音娱乐',
    '海外旅游'
  ]
  onPageShow(): void {
    window.getLastWindow(AppStorage.get("context"), (err, data) => {
      if (err.code) {
        console.error('Failed to get last window. Cause:' + JSON.stringify(err));
        return;
      }
      data.setFullScreen(true)
    });
  }
  build() {
    Column() {
      ForEach(this.titles, (item: string, index: number) => {
        Text(`${index + 1} ${item}`)
          .fontSize(24)
          .fontWeight(700)
          .fontColor(Color.Orange)
          .padding(15)
          .width('100%')
      })
    }

  }
}

5.2.8.2 FofEach案例 -新闻列表

import window from '@ohos.window';
import { it } from '@ohos/hypium';

interface Article {
  title: string
  createTime: string
}

@Entry
@Component

struct Index {
  @State articles: Article[] = [
    {
      title: '近200+自动驾驶数据集全面调研!一览如何数据闭环全流程',
      createTime: '2024-01-31 09:59:43'
    },
    {
      title: 'MySQL Shell 8.0.32 for GreatSQL编译二进制包',
      createTime: '2024-01-31 09:55:53'
    },
    {
      title: '在Redis中如何实现分布式事务的一致性?',
      createTime: '2024-01-31 09:54:51'
    },
  ]
  onPageShow(): void {
    window.getLastWindow(AppStorage.get("context"), (err, data) => {
      if (err.code) {
        console.error('Failed to get last window. Cause:' + JSON.stringify(err));
        return;
      }
      data.setFullScreen(true)
    });
  }
  build() {
  Scroll() {
    Column() {
      // 单个新闻结构
      Column() {
        ForEach( this.articles, (item: Article, Index: number) =>{
          Text(item.title)
            .width('100%')
            .fontSize(15)
            .fontColor('#303030')
            .lineHeight(20)
          Text(item.createTime)
            .margin({top: 15})
            .width('100%')
            .fontSize(12)
            .fontColor('rgb(192, 192, 192)')
        })

      }
      .padding({top: 15, bottom: 15})
      .width('100%')
      .border({
        width: {bottom: 2},
        color: {bottom: '#f4f4f4'}
      })

    }
    .constraintSize({
      minHeight: '100%'
    })
  }
  .padding({ left: 13, right: 13 })
  .width('100%')
  .height('100%')

  }
}

 六、渲染控制综合案例

6.1 生肖抽卡-初始布局-Badge角标组件

import window from '@ohos.window';
@Entry
@Component

struct Index {

  onPageShow(): void {
    window.getLastWindow(AppStorage.get("context"), (err, data) => {
      if (err.code) {
        console.error('Failed to get last window. Cause:' + JSON.stringify(err));
        return;
      }
      data.setFullScreen(true)
    });
  }
  build() {
    Column(){
     Badge({
       count: 1,
       position: BadgePosition.RightTop,
       style: {
         badgeSize: 20,
         fontSize: 14,
         badgeColor: '#fa2aad'
       }
     }){
       Image($r('app.media.bg_01'))
         .width(100)
     }

    }


  }
}

 

6.2 生肖抽卡 - 初始布局-Grid布局

@Entry
@Component
struct Index {
  build() {
    // Grid布局的基本使用: 规则的行列布局中非常常见, 3行4列
    Grid() {
      ForEach([1,2,3,4,5,6,7,8,9,10,11,12], () => {
        GridItem() {
          Column() {

          }
          .width('100%')
          .height('100%')
          .backgroundColor(Color.Green)
          .border({ width: 1 })
        }
      })
    }
    .columnsTemplate('1fr 1fr 1fr 1fr')
    .rowsTemplate('1fr 1fr 1fr')
    .columnsGap(5)
    .rowsGap(5)
    .width('100%')
    .height(500)
    .backgroundColor(Color.Pink)
  }
}

import window from '@ohos.window';
@Entry
@Component

struct Index {

  onPageShow(): void {
    window.getLastWindow(AppStorage.get("context"), (err, data) => {
      if (err.code) {
        console.error('Failed to get last window. Cause:' + JSON.stringify(err));
        return;
      }
      data.setFullScreen(true)
    });
  }
  build() {
    Column(){

    Grid(){
      ForEach([1,2,3,,4,5,6], ()=>{
        GridItem(){
          Badge({
            count: 1,
            position: BadgePosition.RightTop,
            style: {
              badgeSize: 20,
              fontSize: 14,
              badgeColor: '#fa2aad'
            }
          }){
            Image($r('app.media.bg_01'))
              .width(80)
          }


        }
      })

    }
    .columnsTemplate('1fr 1fr 1fr')
    .rowsTemplate('1fr 1fr')
    .width('100%').height(300)
    .margin({top: 100})
      Button('立即抽卡')
        .width(200)
        .backgroundColor('#ed5b8c')
        .margin({top: 50})


    }
  }
}

6.3 生肖抽卡 - 数据动态渲染

import window from '@ohos.window';
// 1. 定义接口 (每个列表项的数据结构)
interface ImageCount {
  url: string
  count: number
}
@Entry
@Component

struct Index {
  // 2. 基于接口, 准备数据
  @State images: ImageCount[] = [
    { url: 'app.media.bg_00', count: 0 },
    { url: 'app.media.bg_01', count: 1 },
    { url: 'app.media.bg_02', count: 2 },
    { url: 'app.media.bg_03', count: 3 },
    { url: 'app.media.bg_04', count: 4 },
    { url: 'app.media.bg_05', count: 5 }
  ]

  onPageShow(): void {
    window.getLastWindow(AppStorage.get("context"), (err, data) => {
      if (err.code) {
        console.error('Failed to get last window. Cause:' + JSON.stringify(err));
        return;
      }
      data.setFullScreen(true)
    });
  }
  build() {
    Column(){

    Grid(){
      ForEach(this.images, (item: ImageCount,Index)=>{
        GridItem(){
          Badge({
            count: item.count,
            position: BadgePosition.RightTop,
            style: {
              badgeSize: 20,
              fontSize: 14,
              badgeColor: '#fa2aad'
            }
          }){
            Image($r(item.url))
              .width(80)
          }


        }
      })

    }
    .columnsTemplate('1fr 1fr 1fr')
    .rowsTemplate('1fr 1fr')
    .width('100%').height(300)
    .margin({top: 100})
      Button('立即抽卡')
        .width(200)
        .backgroundColor('#ed5b8c')
        .margin({top: 50})


    }
  }
}

6.4 生肖抽卡 - 遮罩和显隐动画

6.4.1 抽卡遮罩层

import window from '@ohos.window';
// 1. 定义接口 (每个列表项的数据结构)
interface ImageCount {
  url: string
  count: number
}
@Entry
@Component

struct Index {
  // 2. 基于接口, 准备数据
  @State images: ImageCount[] = [
    { url: 'app.media.bg_00', count: 0 },
    { url: 'app.media.bg_01', count: 1 },
    { url: 'app.media.bg_02', count: 2 },
    { url: 'app.media.bg_03', count: 3 },
    { url: 'app.media.bg_04', count: 4 },
    { url: 'app.media.bg_05', count: 5 }
  ]

  onPageShow(): void {
    window.getLastWindow(AppStorage.get("context"), (err, data) => {
      if (err.code) {
        console.error('Failed to get last window. Cause:' + JSON.stringify(err));
        return;
      }
      data.setFullScreen(true)
    });
  }
  build() {
    Stack(){
      // 初始化的布局结果
      Column(){

        Grid(){
          ForEach(this.images, (item: ImageCount,Index)=>{
            GridItem(){
              Badge({
                count: item.count,
                position: BadgePosition.RightTop,
                style: {
                  badgeSize: 20,
                  fontSize: 14,
                  badgeColor: '#fa2aad'
                }
              }){
                Image($r(item.url))
                  .width(80)
              }


            }
          })

        }
        .columnsTemplate('1fr 1fr 1fr')
        .rowsTemplate('1fr 1fr')
        .width('100%').height(300)
        .margin({top: 100})
        Button('立即抽卡')
          .width(200)
          .backgroundColor('#ed5b8c')
          .margin({top: 50})


      }
      .width('100%').height('100%')
      .backgroundColor(Color.Pink)

      // 抽卡遮罩层
      Column({space: 30}){
        Text('获得生肖卡')
          .fontColor('#f5ebcf')
          .fontSize(25)
          .fontWeight(FontWeight.Bold)
        Image($r('app.media.img_00'))
          .width(200)
        Button('开心收下')
          .width(200).height(50)
          .backgroundColor(Color.Transparent) //透明背景色
          .border({width: 2,color: '#fff9e0'})

      }
      .justifyContent(FlexAlign.Center)
      .width('100%').height('100%')
      // 颜色十六进制色值如果是八位,就是透明度
      .backgroundColor('#cc000000')

    }


  }
}

6.4.2 生肖抽卡 -显隐效果控制

 

import window from '@ohos.window';
// 1. 定义接口 (每个列表项的数据结构)
interface ImageCount {
  url: string
  count: number
}

@Entry
@Component

struct Index {
  // 2. 基于接口, 准备数据
  @State images: ImageCount[] = [
    { url: 'app.media.bg_00', count: 0 },
    { url: 'app.media.bg_01', count: 1 },
    { url: 'app.media.bg_02', count: 2 },
    { url: 'app.media.bg_03', count: 3 },
    { url: 'app.media.bg_04', count: 4 },
    { url: 'app.media.bg_05', count: 5 }
  ]

  //控制遮罩的显隐
  @State maskOpacity: number = 0

  // 层级显隐
  @State maskIndex: number = -1
  // 控制图片的缩放
  @State maskImgX: number = 0
  @State maskImgY: number = 0

  onPageShow(): void {
    window.getLastWindow(AppStorage.get("context"), (err, data) => {
      if (err.code) {
        console.error('Failed to get last window. Cause:' + JSON.stringify(err));
        return;
      }
      data.setFullScreen(true)
    });
  }
  build() {
    Stack(){
      // 初始化的布局结果
      Column(){

        Grid(){
          ForEach(this.images, (item: ImageCount,Index: number)=>{
            GridItem(){
              Badge({
                count: item.count,
                position: BadgePosition.RightTop,
                style: {
                  badgeSize: 20,
                  fontSize: 14,
                  badgeColor: '#fa2aad'
                }
              }){
                Image($r(item.url))
                  .width(80)
              }


            }
          })

        }
        .columnsTemplate('1fr 1fr 1fr')
        .rowsTemplate('1fr 1fr')
        .width('100%').height(300)
        .margin({top: 100})
        Button('立即抽卡')
          .width(200)
          .backgroundColor('#ed5b8c')
          .margin({top: 50})
          .onClick( () => {
            this.maskOpacity = 1
            this.maskIndex = 999
          //   点击时,突破需要缩放
            this.maskImgX = 1
            this.maskImgY = 1
          })


      }
      .width('100%').height('100%')
      // .backgroundColor(Color.Pink)

      // 抽卡遮罩层
      Column({space: 30}){
        Text('获得生肖卡')
          .fontColor('#f5ebcf')
          .fontSize(25)
          .fontWeight(FontWeight.Bold)
        Image($r('app.media.img_00'))
          .width(200)
        // 控制元素的缩放
          .scale({
            x: this.maskImgX,
            y: this.maskImgY
          })
          .animation({
            duration: 500
          })
        Button('开心收下')
          .width(200).height(50)
          .backgroundColor(Color.Transparent) //透明背景色
          .border({width: 2,color: '#fff9e0'})
          .onClick( () => {
            this.maskOpacity = 0
            this.maskIndex = -1
          //   图形重置缩放比为0
            this.maskImgX = 0
            this.maskImgY = 0
          })

      }
      .justifyContent(FlexAlign.Center)
      .width('100%').height('100%')
      // 颜色十六进制色值如果是八位,就是透明度
      .backgroundColor('#cc000000')
      //设置透明度
      .opacity(this.maskOpacity)
      .zIndex(this.maskIndex)
      //   动画 animation
      .animation({
        duration: 200
      })

    }


  }
}

6.4.3 生肖抽卡 -随机卡片

import window from '@ohos.window';
// 1. 定义接口 (每个列表项的数据结构)
interface ImageCount {
  url: string
  count: number
}

@Entry
@Component

struct Index {
  //  随机的生肖卡序号
  @State randomIndex: number = -1 // 还没有开始抽

  // 2. 基于接口, 准备数据
  @State images: ImageCount[] = [
    { url: 'app.media.bg_00', count: 0 },
    { url: 'app.media.bg_01', count: 0 },
    { url: 'app.media.bg_02', count: 0 },
    { url: 'app.media.bg_03', count: 0 },
    { url: 'app.media.bg_04', count: 0 },
    { url: 'app.media.bg_05', count: 0 }
  ]

  //控制遮罩的显隐
  @State maskOpacity: number = 0

  // 层级显隐
  @State maskIndex: number = -1
  // 控制图片的缩放
  @State maskImgX: number = 0
  @State maskImgY: number = 0

  onPageShow(): void {
    window.getLastWindow(AppStorage.get("context"), (err, data) => {
      if (err.code) {
        console.error('Failed to get last window. Cause:' + JSON.stringify(err));
        return;
      }
      data.setFullScreen(true)
    });
  }
  build() {
    Stack(){
      // 初始化的布局结果
      Column(){

        Grid(){
          ForEach(this.images, (item: ImageCount,Index: number)=>{
            GridItem(){
              Badge({
                count: item.count,
                position: BadgePosition.RightTop,
                style: {
                  badgeSize: 20,
                  fontSize: 14,
                  badgeColor: '#fa2aad'
                }
              }){
                Image($r(item.url))
                  .width(80)
              }


            }
          })

        }
        .columnsTemplate('1fr 1fr 1fr')
        .rowsTemplate('1fr 1fr')
        .width('100%').height(300)
        .margin({top: 100})
        Button('立即抽卡')
          .width(200)
          .backgroundColor('#ed5b8c')
          .margin({top: 50})
          .onClick( () => {
            this.maskOpacity = 1
            this.maskIndex = 999
          //   点击时,突破需要缩放
            this.maskImgX = 1
            this.maskImgY = 1
          //    计算随机数 Math.random() [0,1)
            this.randomIndex = Math.floor(Math.random() * 6)
          })


      }
      .width('100%').height('100%')
      // .backgroundColor(Color.Pink)

      // 抽卡遮罩层
      Column({space: 30}){
        Text('获得生肖卡')
          .fontColor('#f5ebcf')
          .fontSize(25)
          .fontWeight(FontWeight.Bold)
        Image($r(`app.media.img_0${this.randomIndex}`))
          .width(200)
        // 控制元素的缩放
          .scale({
            x: this.maskImgX,
            y: this.maskImgY
          })
          .animation({
            duration: 500
          })
        Button('开心收下')
          .width(200).height(50)
          .backgroundColor(Color.Transparent) //透明背景色
          .border({width: 2,color: '#fff9e0'})
          .onClick( () => {
            this.maskOpacity = 0
            this.maskIndex = -1
          //   图形重置缩放比为0
            this.maskImgX = 0
            this.maskImgY = 0
          //   开心收下逻辑,对象数组的情况需要更新,需要修改替换整个对象
          //   this.images[this.randomIndex].url
            this.images[this.randomIndex] ={
              url: `app.media.img_0${this.randomIndex}`,
              count: this.images[this.randomIndex].count + 1

            }
          })

      }
      .justifyContent(FlexAlign.Center)
      .width('100%').height('100%')
      // 颜色十六进制色值如果是八位,就是透明度
      .backgroundColor('#cc000000')
      //设置透明度
      .opacity(this.maskOpacity)
      .zIndex(this.maskIndex)
      //   动画 animation
      .animation({
        duration: 200
      })

    }


  }
}

6.4.4 生肖抽奖 - 抽大奖

6.4.4.1 抽大奖遮罩层

 

import window from '@ohos.window';
// 1. 定义接口 (每个列表项的数据结构)
interface ImageCount {
  url: string
  count: number
}

@Entry
@Component

struct Index {
  //  随机的生肖卡序号
  @State randomIndex: number = -1 // 还没有开始抽

  // 2. 基于接口, 准备数据
  @State images: ImageCount[] = [
    { url: 'app.media.bg_00', count: 0 },
    { url: 'app.media.bg_01', count: 0 },
    { url: 'app.media.bg_02', count: 0 },
    { url: 'app.media.bg_03', count: 0 },
    { url: 'app.media.bg_04', count: 0 },
    { url: 'app.media.bg_05', count: 0 }
  ]

  //控制遮罩的显隐
  @State maskOpacity: number = 0

  // 层级显隐
  @State maskIndex: number = -1
  // 控制图片的缩放
  @State maskImgX: number = 0
  @State maskImgY: number = 0

  onPageShow(): void {
    window.getLastWindow(AppStorage.get("context"), (err, data) => {
      if (err.code) {
        console.error('Failed to get last window. Cause:' + JSON.stringify(err));
        return;
      }
      data.setFullScreen(true)
    });
  }
  build() {
    Stack(){
      // 初始化的布局结果
      Column(){

        Grid(){
          ForEach(this.images, (item: ImageCount,Index: number)=>{
            GridItem(){
              Badge({
                count: item.count,
                position: BadgePosition.RightTop,
                style: {
                  badgeSize: 20,
                  fontSize: 14,
                  badgeColor: '#fa2aad'
                }
              }){
                Image($r(item.url))
                  .width(80)
              }


            }
          })

        }
        .columnsTemplate('1fr 1fr 1fr')
        .rowsTemplate('1fr 1fr')
        .width('100%').height(300)
        .margin({top: 100})
        Button('立即抽卡')
          .width(200)
          .backgroundColor('#ed5b8c')
          .margin({top: 50})
          .onClick( () => {
            this.maskOpacity = 1
            this.maskIndex = 999
          //   点击时,突破需要缩放
            this.maskImgX = 1
            this.maskImgY = 1
          //    计算随机数 Math.random() [0,1)
            this.randomIndex = Math.floor(Math.random() * 6)
          })


      }
      .width('100%').height('100%')
      // .backgroundColor(Color.Pink)

      // 抽卡遮罩层
      Column({space: 30}){
        Text('获得生肖卡')
          .fontColor('#f5ebcf')
          .fontSize(25)
          .fontWeight(FontWeight.Bold)
        Image($r(`app.media.img_0${this.randomIndex}`))
          .width(200)
        // 控制元素的缩放
          .scale({
            x: this.maskImgX,
            y: this.maskImgY
          })
          .animation({
            duration: 500
          })
        Button('开心收下')
          .width(200).height(50)
          .backgroundColor(Color.Transparent) //透明背景色
          .border({width: 2,color: '#fff9e0'})
          .onClick( () => {
            this.maskOpacity = 0
            this.maskIndex = -1
          //   图形重置缩放比为0
            this.maskImgX = 0
            this.maskImgY = 0
          //   开心收下逻辑,对象数组的情况需要更新,需要修改替换整个对象
          //   this.images[this.randomIndex].url
            this.images[this.randomIndex] ={
              url: `app.media.img_0${this.randomIndex}`,
              count: this.images[this.randomIndex].count + 1

            }
          })

      }
      .justifyContent(FlexAlign.Center)
      .width('100%').height('100%')
      // 颜色十六进制色值如果是八位,就是透明度
      .backgroundColor('#cc000000')
      //设置透明度
      .opacity(this.maskOpacity)
      .zIndex(this.maskIndex)
      //   动画 animation
      .animation({
        duration: 200
      })

    //   抽大奖遮罩层
      Column({space: 30}){
        Text('恭喜获得手机一部')
          .fontColor('#f5ebcf')
          .fontSize(25)
          .fontWeight(700)
        Image($r('app.media.pg'))
          .width(300)
        Button('再来一次')
          .width(200).height(50)
          .backgroundColor(Color.Transparent)
          .border({width: 2,color: '#fff9e0'})

      }.width('100%').height('100%')
      .backgroundColor('#cc000000')
      .justifyContent(FlexAlign.Center)

    }


  }
}

 

6.4.4.2 抽大奖显隐控制

import window from '@ohos.window';
// 1. 定义接口 (每个列表项的数据结构)
interface ImageCount {
  url: string
  count: number
}

@Entry
@Component

struct Index {
  //  随机的生肖卡序号
  @State randomIndex: number = -1 // 还没有开始抽

  // 2. 基于接口, 准备数据
  @State images: ImageCount[] = [
    { url: 'app.media.bg_00', count: 0 },
    { url: 'app.media.bg_01', count: 0 },
    { url: 'app.media.bg_02', count: 0 },
    { url: 'app.media.bg_03', count: 0 },
    { url: 'app.media.bg_04', count: 0 },
    { url: 'app.media.bg_05', count: 0 }
  ]

  //控制遮罩的显隐
  @State maskOpacity: number = 0

  // 层级显隐
  @State maskIndex: number = -1
  // 控制图片的缩放
  @State maskImgX: number = 0
  @State maskImgY: number = 0

  // 控制中大奖遮罩层显隐
  @State isGet: boolean = false

  onPageShow(): void {
    window.getLastWindow(AppStorage.get("context"), (err, data) => {
      if (err.code) {
        console.error('Failed to get last window. Cause:' + JSON.stringify(err));
        return;
      }
      data.setFullScreen(true)
    });
  }
  build() {
    Stack(){
      // 初始化的布局结果
      Column(){

        Grid(){
          ForEach(this.images, (item: ImageCount,Index: number)=>{
            GridItem(){
              Badge({
                count: item.count,
                position: BadgePosition.RightTop,
                style: {
                  badgeSize: 20,
                  fontSize: 14,
                  badgeColor: '#fa2aad'
                }
              }){
                Image($r(item.url))
                  .width(80)
              }


            }
          })

        }
        .columnsTemplate('1fr 1fr 1fr')
        .rowsTemplate('1fr 1fr')
        .width('100%').height(300)
        .margin({top: 100})
        Button('立即抽卡')
          .width(200)
          .backgroundColor('#ed5b8c')
          .margin({top: 50})
          .onClick( () => {
            this.maskOpacity = 1
            this.maskIndex = 999
          //   点击时,突破需要缩放
            this.maskImgX = 1
            this.maskImgY = 1
          //    计算随机数 Math.random() [0,1)
            this.randomIndex = Math.floor(Math.random() * 6)
          })


      }
      .width('100%').height('100%')
      // .backgroundColor(Color.Pink)

      // 抽卡遮罩层
      Column({space: 30}){
        Text('获得生肖卡')
          .fontColor('#f5ebcf')
          .fontSize(25)
          .fontWeight(FontWeight.Bold)
        Image($r(`app.media.img_0${this.randomIndex}`))
          .width(200)
        // 控制元素的缩放
          .scale({
            x: this.maskImgX,
            y: this.maskImgY
          })
          .animation({
            duration: 500
          })
        Button('开心收下')
          .width(200).height(50)
          .backgroundColor(Color.Transparent) //透明背景色
          .border({width: 2,color: '#fff9e0'})
          .onClick( () => {
            this.maskOpacity = 0
            this.maskIndex = -1
          //   图形重置缩放比为0
            this.maskImgX = 0
            this.maskImgY = 0
          //   开心收下逻辑,对象数组的情况需要更新,需要修改替换整个对象
          //   this.images[this.randomIndex].url
            this.images[this.randomIndex] ={
              url: `app.media.img_0${this.randomIndex}`,
              count: this.images[this.randomIndex].count + 1

            }
          //   每次收完卡片,需要进行简单的检索,判断是否集齐了
          //   只要有一个是0 就是没有集齐
            let flag: boolean = true //假设集齐
          //   验证是否集齐
            for(let item of this.images) {
              if (item.count == 0) {
                flag = false
                break
              }
            }
            this.isGet = flag


          })

      }
      .justifyContent(FlexAlign.Center)
      .width('100%').height('100%')
      // 颜色十六进制色值如果是八位,就是透明度
      .backgroundColor('#cc000000')
      //设置透明度
      .opacity(this.maskOpacity)
      .zIndex(this.maskIndex)
      //   动画 animation
      .animation({
        duration: 200
      })

    //   抽大奖遮罩层
      if(this.isGet){
        Column({space: 30}){
          Text('恭喜获得手机一部')
            .fontColor('#f5ebcf')
            .fontSize(25)
            .fontWeight(700)
          Image($r('app.media.pg'))
            .width(300)
          Button('再来一次')
            .width(200).height(50)
            .backgroundColor(Color.Transparent)
            .border({width: 2,color: '#fff9e0'})
           

        }.width('100%').height('100%')
        .backgroundColor('#cc000000')
        .justifyContent(FlexAlign.Center)

      }
      }



  }
}

6.4.5 生肖抽卡- 随机抽卡&再来一次

 

import window from '@ohos.window';
// 1. 定义接口 (每个列表项的数据结构)
interface ImageCount {
  url: string
  count: number
}

@Entry
@Component

struct Index {
  //  随机的生肖卡序号
  @State randomIndex: number = -1 // 还没有开始抽

  // 2. 基于接口, 准备数据
  @State images: ImageCount[] = [
    { url: 'app.media.bg_00', count: 0 },
    { url: 'app.media.bg_01', count: 0 },
    { url: 'app.media.bg_02', count: 0 },
    { url: 'app.media.bg_03', count: 0 },
    { url: 'app.media.bg_04', count: 0 },
    { url: 'app.media.bg_05', count: 0 }
  ]

  //控制遮罩的显隐
  @State maskOpacity: number = 0

  // 层级显隐
  @State maskIndex: number = -1
  // 控制图片的缩放
  @State maskImgX: number = 0
  @State maskImgY: number = 0

  // 控制中大奖遮罩层显隐
  @State isGet: boolean = false

  // 奖池
  @State arr: string[] = ['pg', 'hw', 'xm']  //奖池
  @State prize: string = '' //默认没中奖

  onPageShow(): void {
    window.getLastWindow(AppStorage.get("context"), (err, data) => {
      if (err.code) {
        console.error('Failed to get last window. Cause:' + JSON.stringify(err));
        return;
      }
      data.setFullScreen(true)
    });
  }
  build() {
    Stack(){
      // 初始化的布局结果
      Column(){

        Grid(){
          ForEach(this.images, (item: ImageCount,Index: number)=>{
            GridItem(){
              Badge({
                count: item.count,
                position: BadgePosition.RightTop,
                style: {
                  badgeSize: 20,
                  fontSize: 14,
                  badgeColor: '#fa2aad'
                }
              }){
                Image($r(item.url))
                  .width(80)
              }


            }
          })

        }
        .columnsTemplate('1fr 1fr 1fr')
        .rowsTemplate('1fr 1fr')
        .width('100%').height(300)
        .margin({top: 100})
        Button('立即抽卡')
          .width(200)
          .backgroundColor('#ed5b8c')
          .margin({top: 50})
          .onClick( () => {
            this.maskOpacity = 1
            this.maskIndex = 999
          //   点击时,突破需要缩放
            this.maskImgX = 1
            this.maskImgY = 1
          //    计算随机数 Math.random() [0,1)
            this.randomIndex = Math.floor(Math.random() * 6)
          })


      }
      .width('100%').height('100%')
      // .backgroundColor(Color.Pink)

      // 抽卡遮罩层
      Column({space: 30}){
        Text('获得生肖卡')
          .fontColor('#f5ebcf')
          .fontSize(25)
          .fontWeight(FontWeight.Bold)
        Image($r(`app.media.img_0${this.randomIndex}`))
          .width(200)
        // 控制元素的缩放
          .scale({
            x: this.maskImgX,
            y: this.maskImgY
          })
          .animation({
            duration: 500
          })
        Button('开心收下')
          .width(200).height(50)
          .backgroundColor(Color.Transparent) //透明背景色
          .border({width: 2,color: '#fff9e0'})
          .onClick( () => {
            this.maskOpacity = 0
            this.maskIndex = -1
          //   图形重置缩放比为0
            this.maskImgX = 0
            this.maskImgY = 0
          //   开心收下逻辑,对象数组的情况需要更新,需要修改替换整个对象
          //   this.images[this.randomIndex].url
            this.images[this.randomIndex] ={
              url: `app.media.img_0${this.randomIndex}`,
              count: this.images[this.randomIndex].count + 1

            }
          //   每次收完卡片,需要进行简单的检索,判断是否集齐了
          //   只要有一个是0 就是没有集齐
            let flag: boolean = true //假设集齐
          //   验证是否集齐
            for(let item of this.images) {
              if (item.count == 0) {
                flag = false
                break
              }
            }
            this.isGet = flag

          //   判断是否中奖了,如果是,就需要去抽奖
            if (flag){
              let randomIndex: number = Math.floor(Math.random() * 3)
              this.prize = this.arr[randomIndex]
            }


          })

      }
      .justifyContent(FlexAlign.Center)
      .width('100%').height('100%')
      // 颜色十六进制色值如果是八位,就是透明度
      .backgroundColor('#cc000000')
      //设置透明度
      .opacity(this.maskOpacity)
      .zIndex(this.maskIndex)
      //   动画 animation
      .animation({
        duration: 200
      })

    //   抽大奖遮罩层
      if(this.isGet){
        Column({space: 30}){
          Text('恭喜获得手机一部')
            .fontColor('#f5ebcf')
            .fontSize(25)
            .fontWeight(700)
          Image($r(`app.media.${this.prize}`))
            .width(300)
          Button('再来一次')
            .width(200).height(50)
            .backgroundColor(Color.Transparent)
            .border({width: 2,color: '#fff9e0'})
            .onClick( () => {
              this.isGet = false
              this.prize = ''
              this.images = [
                { url: 'app.media.bg_00', count: 0 },
                { url: 'app.media.bg_01', count: 0 },
                { url: 'app.media.bg_02', count: 0 },
                { url: 'app.media.bg_03', count: 0 },
                { url: 'app.media.bg_04', count: 0 },
                { url: 'app.media.bg_05', count: 0 }
              ]

            })


        }.width('100%').height('100%')
        .backgroundColor('#cc000000')
        .justifyContent(FlexAlign.Center)

      }
      }



  }
}

  • 10
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值