demo 英雄热度榜 (条件筛选—高亮切换—列表渲染—日期显示)
英雄热度榜项目笔记
demo名称
英雄热度榜 - 筛选高亮列表展示系统
四个核心功能
1. 筛选条件渲染
功能: 把字符串转成筛选列表
// 字符串转数组 - 用trim()去空格,split("|")按|分割
@State branchFilter: string[] = branchFilter.trim().split("|")// 渲染列表 - ForEach循环渲染每个筛选条件
ForEach(this.branchFilter, (item: string, index: number) => {Text(item)
})
2. 高亮切换
功能: 点击切换高亮效果
// 状态变量 - 记录当前选中的索引,默认0
@State branchFilterActiveIndex: number = 0// 点击切换 - 点击时更新选中索引
.onClick(() => {this.branchFilterActiveIndex = index
})// 样式控制 - 根据索引判断是否高亮,高亮黑色,默认灰色
.fontColor(this.branchFilterActiveIndex === index ? Color.Black : '#aab1b4')
3. 列表渲染
功能: 显示英雄数据列表
// 导入数据 - 从HeroData.ets导入英雄数组,用@State管理状态
@State heroList: Hero[] = heroList// 渲染列表 - ForEach循环渲染每个英雄信息
ForEach(this.heroList, (item: Hero) => {Row() {Image(item.heroIcon) // 头像Text(item.heroName) // 名字Text(item.winRate.toFixed(2) + '%') // 胜率 - toFixed(2)保留2位小数Text(item.showRate.toFixed(2) + '%') // 登场率}
})
4. 渲染日期
功能: 显示当前日期
// 获取日期 - 创建Date对象,提取年月日并格式化
getDate() {const date: Date = new Date()return `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`// getMonth()从0开始,所以要+1
}// 显示日期 - 调用方法获取当前日期并显示
Text(this.getDate())
技术要点
@State
状态管理ForEach
循环渲染.onClick()
点击事件- 条件渲染样式切换
项目结构
my_last.ets # 主页面
HeroData.ets # 数据文件
全部代码
// 导入英雄数据相关接口和数组
import { branchFilter, Hero, heroList } from '../data/HeroData'@Entry
@Component
struct Page07_RankLists {// ========== 状态变量定义 ==========// 筛选条件渲染 - 字符串转数组:用trim()去空格,split("|")按|分割@State branchFilter: string[] = branchFilter.trim().split("|")// 当前选中的筛选条件索引,用于高亮切换@State branchFilterActiveIndex: number = 0// 英雄数据列表 - 用@State管理状态,支持动态更新@State heroList: Hero[] = heroList// 排序条件数组 - 定义可排序的字段sortList: string[] = ['热度', '胜率', '登场率', 'Ban率']// 当前选中的排序索引 - 用于排序高亮显示@State sortIndex: number = -1// ========== 方法定义 ==========// 获取当前日期并格式化为年/月/日格式getDate() {const date: Date = new Date()const year = date.getFullYear() // 获取年份const yue = date.getMonth() + 1 // 获取月份(+1因为月份从0开始)const day = date.getDate() // 获取日期return `${year}/${yue}/${day}` // 返回格式化字符串}build() {Column() {// ========== 顶部背景区域 ==========Stack({ alignContent: Alignment.Top }) {// 背景图片Image($r('app.media.ic_bg_517')).height(180).width('100%')// 顶部操作栏 - 包含返回按钮、标题、日期等Stack() {Row() {// 左侧返回按钮Image($r('app.media.ic_public_arrow_left')).width(24).fillColor(Color.White)// 右侧功能按钮组Row({ space: 10 }) {Image($r('app.media.ic_public_question')) // 帮助按钮.width(24).fillColor(Color.White)Image($r('app.media.ic_public_share')) // 分享按钮.width(24).fillColor(Color.White)}}.width('100%').justifyContent(FlexAlign.SpaceBetween)// 中间标题和日期区域Column() {Row() {Text('英雄热度榜') // 主标题.fontColor(Color.White)Image($r('app.media.ic_public_arrow_down')) // 下拉箭头.width(20).fillColor(Color.White)}Row({ space: 5 }) {Text(this.getDate()) // 显示当前日期.fontColor(Color.White).fontSize(10)Text('算法测试中') // 状态标签.fontColor(Color.White).fontSize(9).backgroundColor('37bdee').padding(1).borderRadius({ topLeft: 6, bottomRight: 6 })}}.layoutWeight(1)}.padding({ top: 10, left: 10, right: 10 }).zIndex(2).height(55).backgroundColor(`rgba(0, 0, 0, 0.2)`) // 半透明背景}// ========== 筛选条件区域 ==========// 水平滚动列表 - 显示分路筛选条件List({ space: 25 }) {ForEach(this.branchFilter, (item: string, index: number) => {ListItem() {Stack({ alignContent: Alignment.Bottom }) {// 筛选条件文本 - 根据选中状态切换颜色Text(item).height(40).padding(10).fontSize(16).fontColor(this.branchFilterActiveIndex === index ? Color.Black : '#aab1b4') // 高亮时显示黑色,默认显示灰色// 底部横线 - 只在选中时显示if (this.branchFilterActiveIndex === index) {Text().height(4).width(20).borderRadius(2).backgroundColor(Color.Orange)}}.height(40)}// 点击事件 - 更新选中的筛选条件索引.onClick(() => {this.branchFilterActiveIndex = index})})}.listDirection(Axis.Horizontal) // 水平排列.scrollBar(BarState.Off) // 隐藏滚动条.width('100%').height(50)// ========== 英雄列表区域 ==========Column() {// 列表头部 - 包含标题和排序按钮Row() {Text('英雄') // 列表标题.fontWeight(900)Blank() // 占位空间// 排序按钮组Row({ space: 16 }) {ForEach(this.sortList, (item: string, index: number) => {Text(item).fontColor(this.sortIndex === index ? '#4AB8D9' : '#000') // 选中时蓝色,默认黑色.fontWeight(900).onClick(() => {this.sortIndex = index // 更新选中的排序索引})})}}.width('100%').padding(10)// 英雄数据列表List() {ForEach(this.heroList, (item: Hero, index: number) => {ListItem() {Row({ space: 14 }) {// 英雄头像Image(item.heroIcon).width(40).borderRadius(10)// 英雄名称和分类Column({ space: 5 }) {Text(item.heroName) // 英雄名称Text(item.heroCareer) // 英雄分类.fontSize(10).fontColor(Color.Gray)}.width(70).alignItems(HorizontalAlign.Start)// 英雄数据展示 - 根据排序状态高亮对应数据Text(item.tRank.toLocaleUpperCase()) // 热度等级.fontWeight(900).fontColor(this.sortIndex == 0 ? '#37bdee' : Color.Black) // 热度排序时高亮.width(45).fontSize(15)Text(item.winRate.toFixed(2) + '%') // 胜率.width(45).fontSize(15).fontColor(this.sortIndex == 1 ? '#37bdee' : Color.Black) // 胜率排序时高亮Text(item.showRate.toFixed(2) + '%') // 登场率.width(45).fontSize(15).fontColor(this.sortIndex == 2 ? '#37bdee' : Color.Black) // 登场率排序时高亮Text(item.banRate.toFixed(2) + '%') // Ban率.width(45).fontSize(15).fontColor(this.sortIndex == 3 ? '#37bdee' : Color.Black) // Ban率排序时高亮}.width('100%')}.padding(10)})}}.layoutWeight(1) // 占据剩余空间}.width('100%').height('100%')}
}
export const branchFilter: string = ' 全部分路 | 对抗路 | 中路 | 发育路 | 游走 | 打野 '// 英雄数据
export interface Hero {banRate: number // ban 率showRate: number // 登场率winRate: number // 胜率tRank: string // 热度heroCareer: string // 英雄分类heroName: string // 名字heroIcon: ResourceStr // 头像heroId: number // id
}// 数组
export const heroList: Hero[] = [{banRate: 0.403,winRate: 0.519,showRate: 0.284,tRank: 't0',heroCareer: '辅助',heroId: 505,heroIcon: $r('app.media.ic_avatar_505'),heroName: '瑶'},{banRate: 0.702,winRate: 0.477,showRate: 0.097,tRank: 't0',heroCareer: '辅助',heroId: 191,heroIcon: $r('app.media.ic_avatar_191'),heroName: '大乔'},{banRate: 0.567,winRate: 0.487,showRate: 0.076,tRank: 't0',heroCareer: '辅助/坦克',heroId: 187,heroIcon: $r('app.media.ic_avatar_187'),heroName: '东皇太一'},{banRate: 0.452,winRate: 0.512,showRate: 0.12,tRank: 't0',heroCareer: '辅助/坦克',heroId: 113,heroIcon: $r('app.media.ic_avatar_113'),heroName: '庄周'},{banRate: 0.356,winRate: 0.503,showRate: 0.162,tRank: 't0',heroCareer: '辅助',heroId: 184,heroIcon: $r('app.media.ic_avatar_184'),heroName: '蔡文姬'},{banRate: 0.482,winRate: 0.475,showRate: 0.082,tRank: 't0',heroCareer: '辅助',heroId: 159,heroIcon: $r('app.media.ic_avatar_159'),heroName: '朵莉亚'},{banRate: 0.022,winRate: 0.495,showRate: 0.297,tRank: 't0',heroCareer: '法师',heroId: 142,heroIcon: $r('app.media.ic_avatar_142'),heroName: '安琪拉'},{banRate: 0.396,winRate: 0.496,showRate: 0.098,tRank: 't0',heroCareer: '法师',heroId: 563,heroIcon: $r('app.media.ic_avatar_563'),heroName: '海诺'},
]
项目摘要
本项目基于 ArkTS 开发英雄热度榜应用,
实现了四个核心功能:筛选条件渲染、高亮切换、列表渲染和日期显示。
主要涉及字符串处理(trim、split)、状态管理(@State)、循环渲染(ForEach)、点击事件处理(onClick)、条件渲染和日期格式化等技术点。
通过这个项目,掌握了 ArkTS 中数据绑定、组件交互、动态样式切换和布局构建的核心技能。