鸿蒙HarmonyOS NEXT开发:简易随机抽人功能,动态展示

效果图:

状态变量定义模块

  • @State name:string[]:这是一个存储所有拟参与抽奖人员姓名的数组,初始化时包含了一系列的姓名。
  • @State selectedName:string[]:用于记录已经被抽中的人员姓名列表,初始为空。
  • @State random:string:保存每次随机抽取到的具体人员姓名,初始为空字符串。
  • @State compile:boolean:决定是否处于编辑状态,初始为 false,表示非编辑状态。
  • @State addName:string:用于存储在编辑状态下输入的新姓名。
  • @State randomList:number[]:存储随机生成的数字列表,用于辅助确定选中状态。
  • @State timeId:number:用于存储延迟函数的时间 ID,执行延迟函数用到
      //拟 姓名数组
      @State name:string[]=['张三','李四','王五','汐月',
        '映雪','俊翔','沐晨','羽灵','梦璃','逸风',
        '嘉悦','静婉','梵音','睿泽宇轩','诗韵雅琪','楚瑶慧敏','子昂思涵','锦程妙晴',
        '雨昕晨熙','明轩紫涵','梓萱靖瑶','宇澄语琴','泽翰悦萱']
      //已抽中的名单列表
      @State selectedName:string[] = []
      //随机抽取到的人
      @State random:string = ''
      //是否为编辑状态
      @State compile:boolean = false
      //添加姓名
      @State addName:string = ''
      //随机抽取到的数字列表
      @State randomList:number[] = []
      //延迟函数的时间id
      @State timeId:number = -1

抽奖按钮模块

当点击抽奖按钮时,首先将上一次抽取的结果 random 置为空。然后清除可能存在的未结束的延迟事件。通过设定 num 为 15,决定生成随机数的次数。在延迟函数中,每 200 毫秒执行一次,先清空 randomList,然后生成 num/3 个随机数。当 num 小于等于 0 时,通过循环确保抽取的姓名不在已抽中的名单中,最后将抽中的姓名加入 selectedName 列表,并清除延迟事件。

        // 编辑状态或已将人抽完时 为禁用状态
        Button('抽奖')
          .enabled(this.selectedName.length < this.name.length && !this.compile)
          .onClick(()=>{
            this.random = ''  //先删除上一次抽中的
            clearInterval(this.timeId)    //为了防止连续点击导致上一个延迟事件未结束 先将上一个杀死
            let num:number=15       //为了生成num/3(取整)个随机数
            this.timeId =setInterval(()=>{    //200ms执行一次
              this.randomList = []      //先清空
              for(let i=0;i<num/3;i++)    //生成num/3(取整)个随机数
                this.randomList.push(Math.floor(Math.random()*this.name.length))
              //最后一次时为确定抽中的姓名
              if(num<=0) {
                //防止抽到重复的人
                let f:boolean = true
                while (f){
                  this.random = this.name[Math.floor(Math.random()*this.name.length)]
                  //抽到的不在已抽中的名单列表中 则跳出循环
                  if(this.selectedName.indexOf(this.random)==-1) f=false
                }
                //将抽到的进行统计 加入列表
                this.selectedName.push(this.random)
                clearInterval(this.timeId)
              }
              num--
            },200)
          })

编辑名单按钮模块

点击编辑名单按钮时,通过 this.compile =!this.compile 切换编辑状态。为编辑状态时渲染不同的视图,可以点击右上角的x删除该姓名,也可以通过输入框添加姓名。

重置按钮模块

点击重置按钮,将已抽中的名单 selectedName 清空,同时将随机抽取的结果 random 和随机数字列表 randomList 也都重置为空。

姓名展示视图模块

在编辑状态下,会显示添加姓名的输入框和确定按钮。对于每个姓名,通过判断其在随机数字列表中的索引或是否与随机抽取的结果相同,来设置不同的字体颜色和边框颜色。在编辑状态下,还会显示删除符号,点击可删除对应的姓名。

比如,在显示姓名时,如果某个姓名处于被抽取的状态,其颜色和边框会相应变化,以突出显示。

通过合理的状态管理和逻辑控制,实现了一个简单但实用的随机抽人功能,并提供了编辑和重置的功能,具有一定的灵活性和可用性。

      // 所有姓名的展示视图
      Flex({wrap:FlexWrap.Wrap}){
        //  编辑状态时 可添加姓名
        if(this.compile)
        Row({space:10}){
          TextInput({placeholder:'添加姓名'})
            .onChange((value:string)=>{this.addName = value})
            .layoutWeight(1)
          Button('确定')
            .onClick(()=>{this.name.push(this.addName)})
        }

        ForEach(this.name,(item:string, index:number)=>{
          //  设置选中状态和为选中状态的样式
          Row(){
            Row(){
              Text(item)
                .borderWidth(2)
                .padding(5)
                .fontColor((this.randomList.indexOf(index)!=-1||this.random==item)?Color.Orange:Color.Black)
                .borderColor((this.randomList.indexOf(index)!=-1||this.random==item)?Color.Red:Color.Black)
            }
            .margin(5)
            .border({width:3,color:this.random==item?Color.Red:Color.Transparent})
            // 编辑状态 显示x删除符号
            if(this.compile)
              Text('+')
                .fontSize(21)
                .fontWeight(800)
                .rotate({angle:45})   //旋转45度
                .position({right:2,top:-2})
                .onClick(()=>{
                  this.name.splice(index,1)   //删除
                })
          }
        })
      }
      .width('100%')

完整代码:

@Entry
@Component
struct IndexPage {

  //拟 姓名数组
  @State name:string[]=['张三','李四','王五','汐月',
    '映雪','俊翔','沐晨','羽灵','梦璃','逸风',
    '嘉悦','静婉','梵音','睿泽宇轩','诗韵雅琪','楚瑶慧敏','子昂思涵','锦程妙晴',
    '雨昕晨熙','明轩紫涵','梓萱靖瑶','宇澄语琴','泽翰悦萱']
  //已抽中的名单列表
  @State selectedName:string[] = []
  //随机抽取到的人
  @State random:string = ''
  //是否为编辑状态
  @State compile:boolean = false
  //添加姓名
  @State addName:string = ''
  //随机抽取到的数字列表
  @State randomList:number[] = []
  //延迟函数的时间id
  @State timeId:number = -1
  build() {
    Column({space:10}) {
      // 已抽中的名单
      Column(){
        Text('已抽中的名单:')
        Flex({wrap:FlexWrap.Wrap}){
          ForEach(this.selectedName,(item:string)=>{
              Text(item)
                .padding(5)
                .height(32)
                .margin(5)
          })
        }
        .width('100%')
      }
      .alignItems(HorizontalAlign.Start)
      Row({space:10}){
        // 编辑状态或已将人抽完时 为禁用状态
        Button('抽奖')
          .enabled(this.selectedName.length < this.name.length && !this.compile)
          .onClick(()=>{
            this.random = ''  //先删除上一次抽中的
            clearInterval(this.timeId)    //为了防止连续点击导致上一个延迟事件未结束 先将上一个杀死
            let num:number=15       //为了生成num/3(取整)个随机数
            this.timeId =setInterval(()=>{    //200ms执行一次
              this.randomList = []      //先清空
              for(let i=0;i<num/3;i++)    //生成num/3(取整)个随机数
                this.randomList.push(Math.floor(Math.random()*this.name.length))
              //最后一次时为确定抽中的姓名
              if(num<=0) {
                //防止抽到重复的人
                let f:boolean = true
                while (f){
                  this.random = this.name[Math.floor(Math.random()*this.name.length)]
                  //抽到的不在已抽中的名单列表中 则跳出循环
                  if(this.selectedName.indexOf(this.random)==-1) f=false
                }
                //将抽到的进行统计 加入列表
                this.selectedName.push(this.random)
                clearInterval(this.timeId)
              }
              num--
            },200)
          })
        Button('编辑名单')
          .onClick(()=>{this.compile=!this.compile})
        Button('重置')
          .onClick(()=>{this.selectedName=[]
          this.random = ''
          this.randomList=[]})
      }
      // 所有姓名的展示视图
      Flex({wrap:FlexWrap.Wrap}){
        //  编辑状态时 可添加姓名
        if(this.compile)
        Row({space:10}){
          TextInput({placeholder:'添加姓名'})
            .onChange((value:string)=>{this.addName = value})
            .layoutWeight(1)
          Button('确定')
            .onClick(()=>{this.name.push(this.addName)})
        }

        ForEach(this.name,(item:string, index:number)=>{
          //  设置选中状态和为选中状态的样式
          Row(){
            Row(){
              Text(item)
                .borderWidth(2)
                .padding(5)
                .fontColor((this.randomList.indexOf(index)!=-1||this.random==item)?Color.Orange:Color.Black)
                .borderColor((this.randomList.indexOf(index)!=-1||this.random==item)?Color.Red:Color.Black)
            }
            .margin(5)
            .border({width:3,color:this.random==item?Color.Red:Color.Transparent})
            // 编辑状态 显示x删除符号
            if(this.compile)
              Text('+')
                .fontSize(21)
                .fontWeight(800)
                .rotate({angle:45})   //旋转45度
                .position({right:2,top:-2})
                .onClick(()=>{
                  this.name.splice(index,1)   //删除
                })
          }
        })
      }
      .width('100%')
    }
    .padding(15)
    .height('100%')
    .width('100%')
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值