这个文章将使用arkts语言实现一个简单的前端随机点名程序,有需要的同学可以参考这篇文章,学习arkts的一些基础语法。涉及接口的定义,状态变量的使用,定时器的使用,滑动组件的使用,以及list的使用和渲染。
一、项目展示
在未开始点名时,我们可以看到当前状态为未抽取,点名的头像和姓名都没有显示,抽取记录为空。
点击抽奖后,头像和姓名开始随机变换,三秒后停止,并将最终结果停在学生身上,抽奖记录输出点到的人
二、项目代码
我会把一些比较重要的点在注释中写出来
interface Student{
name:string
logo:Resource
time?: Date //由于我们渲染抽奖列表的时候需要用到它,但是在渲染抽奖
//状态的时候并不会用到它,所以可以在这里加一个?表示用没有这个参数都可以
}
@Entry
@Component
struct Index {
@State username: string = ""
@State userLogo: Resource = $r('app.media.touxiang0')
@State state: number = 0
@State textState: string = "待抽取"
@State stu: Student[] = [
{ name: "张三", logo: $r('app.media.touxiang') },
{ name: "李四", logo: $r('app.media.touxiang2') },
{ name: "王五", logo: $r('app.media.touxiang3') },
{ name: "赵六", logo: $r('app.media.touxiang4') },
{ name: "钱七", logo: $r('app.media.touxiang5') },
{ name: "孙八", logo: $r('app.media.touxiang6') }
]
@State stu2: Student[] = []
private timerId: number = 0 // 用于存储定时器ID
build() {
Column() {
// 随机点名程序标题
Text("随机点名程序")
.fontSize(60)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 10 })
// 抽取状态显示
Text(this.textState)
.fontSize(30)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 10 })
// 抽取按钮
Button("开始点名")
.onClick(() => {
this.state = 1
this.textState = "抽取中..."
// 启动定时器,每隔 100ms 切换一次
this.timerId = setInterval(() => {
let j = Math.floor(Math.random() * this.stu.length)
//这里使用了Math工具类,Math.random会返回一个[0,1)之间的数,Math.floor可以下取整,最后可以得到一个在0~stu.length - 1之间的整数作为索引
this.username = this.stu[j].name
this.userLogo = this.stu[j].logo
}, 100)
// 3 秒后停止定时器,确定最终结果
setTimeout(() => {
clearInterval(this.timerId) // 停止定时器
this.textState = "抽取完成"
this.stu2.push({ name: this.username, logo: this.userLogo , time: new Date()})
}, 3000)
})
.margin({ bottom: 10 })
// 显示头像
Image(this.userLogo)
.width(200)
.height(200)
.margin({ bottom: 10 })
// 显示用户名
Text(this.username)
.fontSize(30)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 10 })
Column(){
Text("抽取记录")
.fontSize(30)
.fontWeight(FontWeight.Bold)
.margin({ bottom: 10 })
Scroll(){
List(){
// 抽取记录
ForEach(this.stu2, (stu: Student, index) => {
// 显示抽取记录
ListItem() {
Row() {
Image(stu.logo)
.width(50)
.height(50)
.margin({ right: 10 })
Text(stu.name)
.fontSize(30)
.fontWeight(FontWeight.Bold)
//显示抽取时间
Text(stu.time?.toLocaleString() ?? '')
.fontSize(20)
.fontWeight(FontWeight.Bold)
.margin({ left: 10 })
}.margin({ bottom: 5 })
}
}, (stu: Student) => stu.name + '')
}
}
}.width("95%").backgroundColor('#ffefeeee')
.height('240vp')
}.justifyContent(FlexAlign.Center)
.width("100%")
}
}
总结
List
仅支持ListItem、ListItemGroup子组件,支持渲染控制类型(if/else、ForEach、LazyForEach和Repeat)。
说明
List的子组件的索引值计算规则:
按子组件的顺序依次递增。
if/else语句中,只有条件成立的分支内的子组件会参与索引值计算,条件不成立的分支内子组件不计算索引值。
ForEach/LazyForEach/Repeat语句中,会计算展开所有子节点索引值。
if/else、ForEach、LazyForEach和Repeat发生变化以后,会更新子节点索引值。
ListItemGroup作为一个整体计算一个索引值,ListItemGroup内部的ListItem不计算索引值。
List子组件visibility属性设置为Hidden或None依然会计算索引值。