效果图:
状态变量定义模块:
@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%')
}
}