四轮乘风街头为王:基于HarmonyOS ArkTS API 24的QQ滑板滑起来街头黑荧光橙红潮酷风与滑板闪电火焰粒子动画系统全记录

本文基于 HarmonyOS NEXT(API 24)ArkTS 声明式 UI 框架,完整拆解一个滑板主题社交应用「QQ滑板·滑起来」的源码实现。应用以街头黑 #1B1B1F 为深色主色、荧光橙红 #FF5A36 为强调色,构建了底部 4 Tab(地形/视频/装备/我的)+ 顶部 6 Tab(广场/滑板场/U池/街式/碗池/平花)的双层导航体系,配套 14 个滑板闪电火焰粒子的向下飘动动画、本周各点位人气值双色柱状图、9 招平花招式库、4 个模态弹窗(发布视频新增/晒新装备新增/删除视频删除/地形详情查询),覆盖从地形发现、视频发布、装备管理到个人招式进度的完整滑板社交闭环。

QQ滑板·滑起来整体运行效果

一、引言:Skate or Die,今天去哪儿浪

滑板正在从小众极限运动变成年轻人的街头生活方式。一块板、四个轮、一双鞋,在城市的台阶扶手斜台之间穿梭,用 Ollie 和 Kickflip 丈量城市。「QQ滑板·滑起来」正是为这一生活方式打造的移动端社区应用:用户可以按地形类型(广场/滑板场/U池/街式/碗池/平花)发现滑板点位、发布滑板视频记录新招、管理自己的装备库、在个人中心追踪滑行天数与招式掌握进度。

应用的视觉语言高度统一:街头黑代表硬核与态度,荧光橙红代表激情与能量,浅灰 #F2F2F4 底色模拟水泥地面的质感。粒子系统选用滑板 🛹、闪电 ⚡、火焰 🔥、星光 ✨、星轨 💫、旋风 🌪️ 六种图标循环,以不同速度向下飘动——这一设计巧妙模拟了滑板从台阶上跃下、火焰从板尾拖出、旋风从轮下卷起的街头运动意象,与向上飘动的常规粒子形成鲜明反差。

本文将从架构概览、色彩系统、数据模型、工具函数与筛选函数、粒子动画系统、双层导航、6 大地形差异化布局、视频/装备/我的三大 Tab、4 个模态弹窗、特性对比、完整代码、开发环境搭建等维度,对源码 1094.ets 进行逐模块深度解析。

二、架构概览:单文件声明式组件 + 状态驱动

整个应用采用 ArkTS 声明式 UI 范式,全部逻辑收敛在一个 @Entry @Component struct SkatePage 主组件中,通过 @State 装饰器驱动视图刷新。架构上可分为以下几层:

  • 常量层SKATE_COLORS 配色对象、BOTTOM_TABS/TOP_TABS 导航配置、SPOTS(15 个地形)/VIDEOS(8 条视频)/GEARS(8 件装备)/TRICKS(9 个招式)/SPOT_REVIEWS(3 条点评)五大业务数据数组、CROWD_BARS/CROWD_LABELS 人气柱状图数据。
  • 接口层ColorPalette/TabItem/ParticleItem/SpotItem/VideoItem/GearItem/TrickItem/SpotReview 共 8 个 interface,强类型约束所有数据结构。
  • 工具函数层difficultyBadge(难度 4 色映射)、feeBadgeColor(收费 2 色映射)、crowdLabel(人气 4 档文案)、crowdBarHeight(柱状图高度换算),共 4 个工具函数。
  • 筛选函数层plazaSpots/parkSpots/rampSpots/streetSpots/bowlSpots/flatSpots,共 6 个 SPOTS.filter() 筛选函数,为 6 大顶部 Tab 提供数据来源。
  • 组件层:主组件 SkatePage 内部通过 @Builder 装饰器定义了头部、顶部 Tab、底部 Tab、6 个地形内容构建器、视频/装备/我的内容构建器、4 个弹窗构建器,共 19 个 @Builder 方法。
  • 状态层:18 个 @State 变量 + 1 个 private timerId,覆盖当前 Tab、弹窗显隐、表单数据、粒子数组、定时器 ID。
  • 生命周期层aboutToAppear 中构建粒子并启动 setInterval 130ms 定时器;aboutToDisappearclearInterval 释放资源。

QQ滑板架构与广场Tab运行效果

主组件的 build() 方法以 Stack 为根容器,底层是 Column 布局的主界面(头部 + 顶部 Tab + 滚动内容区 + 底部 Tab),上层叠加 ForEach 渲染的粒子层,最上层是 4 个条件渲染的模态弹窗遮罩。这种 Stack 分层结构保证了粒子始终浮在内容之上、弹窗始终浮在最顶层。

三、色彩系统:街头黑主色 + 荧光橙红强调 + 潮酷街头风

应用的配色通过 ColorPalette 接口约束,由 SKATE_COLORS 常量统一提供,共 11 个色值(比常规应用多 2 个,新增 dark 街头黑和 darkCard 深灰卡片):

色值名 HEX 用途
primary #FF5A36 荧光橙红主色,强调按钮、标签、下划线、统计数字、柱状图
primaryDeep #C93A1D 深橙红,渐变终止色、激活文字
dark #1B1B1F 街头黑,头部渐变、底部 Tab 底、弹窗头、按钮、彩蛋点位
darkCard #26262C 深灰卡片,U池卡片底、视频封面底、剪辑风格选中底
accentSoft #FFE9E3 浅橙红,标签背景、输入框背景、激活 Tab 底
bg #F2F2F4 页面底色,水泥浅灰
card #FFFFFF 卡片背景
textMain #22222A 主文字,深黑灰
textSub #8C8C96 次级文字,灰
line #E6E6EA 分割线与边框,浅灰

除了这 11 个基础色,应用还在多个场景中引入了辅助色以丰富视觉层次:

  • 难度映射difficultyBadge 函数为 4 档难度分配专属色——★★★★★ #C0392B 红(地狱级)、★★★★ #FF5A36 荧光橙红(高手级)、★★★ #E8A33D 金(进阶级)、其他 #8FBF7F 草绿(入门级)。这一函数在广场 Tab 的横滑大卡中广泛使用,用颜色直观表达地形难度。
  • 收费映射feeBadgeColor 函数为收费方式分配色——免费 #5B8C5A 草绿、其他 #C9862B 金。
  • 人气映射crowdLabel 函数为人气值分配 4 档文案——>=95「卷王聚集地」、>=85「氛围火热」、>=75「人气在线」、其他「清净好去处」。
  • 招式等级映射:平花 Tab 的招式格子中,高手 #C0392B 红、进阶 #FF5A36 荧光橙红、入门 #8FBF7F 草绿,用颜色区分招式难度。
  • 危险/删除#C0392B 红色,用于删除按钮、地狱级难度、确认删除按钮。
  • 成功/服役#5B8C5A 草绿,用于免费标签、正在服役状态、天天滑按钮、累计板时统计。

QQ滑板滑板场Tab与U池Tab运行效果

渐变的运用是本应用色彩表达的重点:头部使用 linearGradient angle:160 colors:[[#1B1B1F,0],[#FF5A36,1]] 街头黑到荧光橙红渐变(从黑到橙红的渐变模拟滑板从阴影中冲向阳光的街头意象,是所有应用中最具冲击力的头部渐变);滑板场 Tab banner 使用暗黑渐变 #26262C→#FF5A36;发布视频弹窗头使用街头黑到深橙红渐变 #1B1B1F→#C93A1D;地形详情弹窗头使用同样的街头黑到深橙红渐变。晒新装备弹窗头使用纯浅橙红 #FFE9E3 底(深字,是所有弹窗中唯一用浅色头的),与其他街头黑渐变头形成鲜明对比。不同弹窗通过头色快速区分交互类型。

底部 Tab 用街头黑底是本应用最具辨识度的视觉特征——所有应用中唯一底部导航栏使用深色底(#1B1B1F),激活态用深橙红 #C93A1D 字,非激活态用灰 #9A9AA4 字,配合 shadow offsetY:-3 顶部阴影,营造出滑板鞋踩在黑色磨砂板面上的潮酷质感。

四、数据模型设计:8 个 interface 强类型约束

应用定义了 8 个 interface,覆盖配色、导航、粒子、地形、视频、装备、招式、点评八大领域:

4.1 ColorPalette、TabItem 与 ParticleItem

interface ColorPalette {
  primary: string
  primaryDeep: string
  dark: string
  darkCard: string
  accentSoft: string
  bg: string
  card: string
  textMain: string
  textSub: string
  line: string
}

interface TabItem {
  label: string
  icon: string
}

interface ParticleItem {
  id: number
  icon: string
  x: number
  y: number
  size: number
  opacity: number
  speed: number
}

ColorPalette 比常规应用多了 darkdarkCard 两个字段,适配滑板主题的街头黑与深灰卡片需求。ParticleItem 新增了 speed 字段,每个粒子拥有独立的飘动速度 0.35 + (i % 5) * 0.12,范围 0.35~0.83,形成快慢错落的自然感。x/y 采用百分比坐标(0~100),渲染时通过 p.x.toString() + '%' 转为百分比定位。

4.2 SpotItem 地形模型(核心)

interface SpotItem {
  id: number
  name: string
  city: string
  type: string
  surface: string
  difficulty: string
  fee: string
  light: string
  rating: string
  skaters: number
  tags: string[]
  desc: string
}

地形模型是应用最复杂的数据结构,13 个字段覆盖了滑板地形的完整信息:id 唯一标识、name 地形名、city 城市地区、type 地形类型(广场/滑板场/U池/街式/碗池/平花)、surface 地面材质(大理石/花岗岩/水泥/专业道具/木质/沥青等)、difficulty 难度星级、fee 收费方式、light 照明情况(通宵亮灯/到22点/室内营业/路灯等)、rating 评分、skaters 人气值(0~100)、tags 地形标签数组、desc 详细描述。

surfacelight 是本应用数据模型的特色字段:surface 记录地面材质(滑板玩家非常在意地面顺滑度),light 记录照明情况(夜滑玩家关注亮灯时间),这两个字段让地形信息更贴近滑板玩家的实际需求。

SPOTS 常量预置了 15 个地形,从武汉江滩极限广场、中山公园入口广场、汉口江滩碗池、光谷滑板公园,到长沙 StreetWare 街区公园、梅溪湖大 U 池、麓谷室内滑板馆,到广州珠江新城广场带、大学城碗池群、琶洲街式公园,到上海西岸滑板公园、永嘉路平花角,到北京首钢极限公园、什刹海周边街区、奥林匹克森林公园广场,覆盖武汉/长沙/广州/上海/北京五大城市六大地形类型,每个地形的 surface/difficulty/fee/light/skaters/tags/desc 都精心设计以匹配地形特色。

4.3 VideoItem 视频模型、GearItem 装备模型、TrickItem 招式模型与 SpotReview 点评模型

interface VideoItem {
  id: number
  title: string
  skater: string
  spot: string
  trick: string
  likes: number
  comments: number
  duration: string
  cover: string
}

interface GearItem {
  id: number
  name: string
  brand: string
  spec: string
  price: number
  status: string
  icon: string
}

interface TrickItem {
  name: string
  level: string
  direction: string
  tip: string
  icon: string
}

interface SpotReview {
  user: string
  starStr: string
  text: string
  time: string
}

VideoItem 10 字段记录视频信息,VIDEOS 预置 8 条(十二级大台阶 Ollie 一次过、碗池深处 carve 出弧线、5050 磨扶手整整五米、两米大 U first air 纪念等),cover 字段用 Emoji 作为视频封面图标,trick 字段记录视频中的招式名称。GearItem 7 字段记录装备信息,GEARS 预置 8 件(全套街头板/进口专业板/轴承/轮子/护具/限量联名板面/滑板鞋/打蜡砖),status 包括正在服役/已退役/常备/收藏中/已磨穿。TrickItem 5 字段记录招式信息,TRICKS 预置 9 个招式(荡板/Ollie/Shove-it/Manual/50-50/Kickflip/Tre Flip/Air/Rock Slide),每个招式含 level(入门/进阶/高手)、direction(平地/道具/U池/碗池)、tip(动作要领),是平花招式库和碗池进阶之路的数据来源。SpotReview 4 字段记录点评,starStr 用 Emoji 星号字符串直接渲染,SPOT_REVIEWS 预置 3 条(评价用户名「每天滑两小时」「摔了但值得」「板龄三年的菜鸡」充满滑板圈梗文化)。

五、工具函数与筛选函数:4 工具 + 6 筛选驱动视觉映射与数据分发

应用定义了 4 个工具函数和 6 个筛选函数,工具函数负责将数据值映射为视觉属性,筛选函数负责为 6 大顶部 Tab 提供数据来源。

5.1 四个工具函数

function difficultyBadge(diff: string): string {
  if (diff === '★★★★★') return '#C0392B'
  if (diff === '★★★★') return '#FF5A36'
  if (diff === '★★★') return '#E8A33D'
  return '#8FBF7F'
}

function feeBadgeColor(fee: string): string {
  if (fee === '免费') return '#5B8C5A'
  return '#C9862B'
}

function crowdLabel(n: number): string {
  if (n >= 95) return '卷王聚集地'
  if (n >= 85) return '氛围火热'
  if (n >= 75) return '人气在线'
  return '清净好去处'
}

function crowdBarHeight(n: number): string {
  return (n * 1.05).toString() + 'vp'
}
  • difficultyBadge:将难度星级映射为 4 色(红/荧光橙红/金/草绿),是本应用最具特色的工具函数,用颜色直观表达地形难度。
  • feeBadgeColor:将收费方式映射为 2 色(免费草绿/收费金),在滑板场 Tab 的费用标签中使用。
  • crowdLabel:将人气值映射为 4 档文案(卷王聚集地/氛围火热/人气在线/清净好去处),在广场 Tab 的地形列表中以荧光橙红字渲染。「卷王聚集地」是滑板圈黑话,形容滑手多到卷起来的场地。
  • crowdBarHeight:将人气值换算为柱状图高度 vp(n * 1.05),在广场 Tab 的本周各点位人气值柱状图中使用。

5.2 六个筛选函数

function plazaSpots(): SpotItem[] { return SPOTS.filter(s => s.type === '广场') }
function parkSpots(): SpotItem[] { return SPOTS.filter(s => s.type === '滑板场') }
function rampSpots(): SpotItem[] { return SPOTS.filter(s => s.type === 'U池') }
function streetSpots(): SpotItem[] { return SPOTS.filter(s => s.type === '街式') }
function bowlSpots(): SpotItem[] { return SPOTS.filter(s => s.type === '碗池') }
function flatSpots(): SpotItem[] { return SPOTS.filter(s => s.type === '平花') }

6 个筛选函数均为 SPOTS.filter() 的纯函数,按 type 精确筛选,对应广场/滑板场/U池/街式/碗池/平花六个顶部 Tab。这种「工具函数 + 筛选函数」的分层设计,让数据映射与数据分发各司其职,模板中只需调用对应函数即可获得正确数据,保持模板简洁。

六、粒子动画系统:14 粒子独立速度向下飘动(滑板闪电火焰街头意象)

粒子系统是本应用的动态灵魂,选用滑板 🛹、闪电 ⚡、火焰 🔥、星光 ✨、星轨 💫、旋风 🌪️ 六种图标循环,以独立速度向下飘动,模拟滑板从台阶跃下、火焰从板尾拖出、旋风从轮下卷起的街头运动意象。

6.1 粒子构建:14 粒子 6 图标循环

buildParticles(): ParticleItem[] {
  const arr: ParticleItem[] = []
  const icons: string[] = ['🛹', '⚡', '🔥', '✨', '💫', '🌪️']
  for (let i = 0; i < 14; i++) {
    arr.push({
      id: i,
      icon: icons[i % icons.length],
      x: (i * 49) % 100,
      y: (i * 73) % 90,
      size: 10 + (i * 9) % 16,
      opacity: 0.2 + (i % 4) * 0.1,
      speed: 0.35 + (i % 5) * 0.12
    })
  }
  return arr
}

14 个粒子通过质数乘法 (i * 49) % 100(i * 73) % 90 生成伪随机分布的 x/y 百分比坐标。图标在 🛹⚡🔥✨💫🌪️ 六种中循环(滑板/闪电/火焰/星光/星轨/旋风),size 范围 10~25,opacity 范围 0.2~0.5,speed 范围 0.35~0.83(每个粒子独立速度,是近期应用中较快的粒子速度,模拟滑板运动的速度感)。

6.2 粒子驱动:向下飘动 + 顶部循环

driftParticles(): void {
  const next: ParticleItem[] = []
  for (const p of this.particles) {
    let ny: number = p.y + p.speed
    if (ny > 96) {
      ny = -6
    }
    next.push({
      id: p.id, icon: p.icon, x: p.x, y: ny,
      size: p.size, opacity: p.opacity, speed: p.speed
    })
  }
  this.particles = next
}

关键点:每帧将每个粒子的 y 坐标加上自身 speed(向下飘动),当 y > 96(飘出底部)时重置为 -6(从顶部重新进入),实现无限循环。x 坐标保持不变(纯垂直下落)。这一方向设计模拟了滑板从台阶上跃下落地、火焰从板尾向后拖出下落、旋风从轮下卷起向下扩散的街头运动意象,与常规上升粒子形成鲜明反差。

6.3 生命周期与渲染

aboutToAppear(): void {
  this.particles = this.buildParticles()
  this.timerId = setInterval(() => {
    this.driftParticles()
  }, 130)
}

aboutToDisappear(): void {
  if (this.timerId >= 0) clearInterval(this.timerId)
}

aboutToAppear 中先构建粒子数组,再启动 setInterval 130ms 定时器(约 7.7fps,配合较快的粒子速度,模拟滑板运动的速度感与街头的节奏感),将定时器 ID 存入 private timerIdaboutToDisappear 中清除定时器。

渲染层在 Stack 中通过 ForEach 遍历粒子,position 使用百分比坐标 x% y%ForEach 的 key 函数使用 'p' + p.id(仅 id,不含 y),避免每帧销毁重建所有粒子节点。

七、双层导航架构:底部 4 Tab + 顶部 6 Tab

应用采用双层 Tab 导航,底部 Tab 切换大模块、顶部 Tab 在「地形」模块内切换地形类型分类。

7.1 头部 headerBuilder:街头黑到荧光橙红渐变 + 今日滑手卡片

头部使用 angle:160 街头黑到荧光橙红渐变 #1B1B1F→#FF5A36(从黑到橙红的渐变模拟滑板从阴影中冲向阳光的街头意象,是所有应用中最具冲击力的头部渐变),左侧是应用名「滑起来」24sp 粗体白字 + 副标题「Skate or Die · 今天去哪儿浪」12sp #FFB3A0 淡橙字,右侧是一个滑手卡片(#2E2E36 深灰底圆角 12):🔥 火焰图标 16sp + 「今日滑手 2140」9sp 淡橙字。深灰卡片在街头黑到荧光橙红渐变头部上形成层次,是滑板应用「街头硬核」视觉隐喻的体现。「Skate or Die」是滑板圈经典口号,意为「不滑即死」,体现滑板文化的硬核态度。

7.2 顶部 Tab topTabsBuilder(仅地形 Tab 显示,6 Tab 等宽)

6 个 Tab 等宽排列(广场🏛️/滑板场🏟️/U池🌊/街式🚧/碗池🥣/平花✨),每个 Tab layoutWeight(1) 等宽。每个 Tab 显示图标 15sp + 文字 11sp。激活态为 #C93A1D 深橙红字粗体 + 荧光橙红 #FF5A36 圆角下划线(Divider width16 strokeWidth3 borderRadius2,圆角下划线是本应用顶部 Tab 的特色细节),非激活态为 #9A9AA4 灰字 + 图标 opacity:0.45。顶部 Tab 使用白底。点击切换 currentTopTab

7.3 底部 Tab bottomTabsBuilder(街头黑底,唯一深色底底部导航)

4 个 Tab(地形🛹/视频🎬/装备🧢/我的👤)等宽排列,激活态为 #C93A1D 深橙红字粗体 + 图标 opacity:1,非激活态为 #9A9AA4 灰字 + 图标 opacity:0.45。底部 Tab 使用街头黑 #1B1B1F(所有应用中唯一底部导航栏使用深色底的),配合 shadow radius:8 color:'26000000' offsetY:-3 顶部阴影,营造出滑板鞋踩在黑色磨砂板面上的潮酷质感。点击切换 currentBottomTab

八、地形 Tab:6 大地形差异化布局

地形 Tab 是应用最核心的模块,6 个顶部 Tab 对应 6 种完全不同的布局风格,从广场的横滑大卡+人气双色柱状图、滑板场的暗黑渐变 banner+双列瀑布、U池的暗黑大卡列表、街式的标签云+紧凑列表+彩蛋点位、碗池的招式时间轴+碗池列表、到平花的三列招式格+平花点位,每种地形都有专属的视觉语言。

8.1 广场 plazaContent:横滑大卡 + 人气双色柱状图 + 广场列表

广场 Tab 由三部分组成:

  1. 标题:「🏛️ 城市广场地形图鉴」15sp 粗体主文字。
  2. 横滑大卡Scroll horizontal 横向滚动,plazaSpots() 筛选出 4 个广场地形(江滩极限广场/中山公园入口广场/珠江新城广场带/奥林匹克森林公园广场),每个渲染为 width:160 的白底圆角 16 卡片,包含:地形名 15sp 粗体、城市·地面材质 10sp 次级文字、难度星级 11sp(difficultyBadge 映射色粗体)、⭐评分 12sp 粗体金字 + fee(feeBadgeColor 映射色粗体)。横滑大卡适合广场地形的「城市地标」展示。
  3. 本周各点位人气值柱状图:标题「📊 本周各点位人气值」,下方是一个白底圆角 16 卡片(height:190,alignItems:VerticalAlign.Bottom 底部对齐),内含 Row 布局的 7 根柱子(CROWD_BARS = [96,78,85,94,82,71,91],对应江滩/中山/汉口碗/光谷/街Ware/麓谷/大学城)。每根柱子通过 crowdBarHeight(n) 计算高度(n * 1.05),使用双色交替——idx % 2 === 0 荧光橙红 #FF5A36,其他街头黑 #1B1B1F,柱子顶部标注人气值数字(#FF5A36 荧光橙红字),底部标注点位简称。7 根柱子等宽排列,底部对齐,双色交替形成强烈的街头视觉冲击,江滩 96 最高形成「卷王聚集地」可视化。
  4. 广场列表plazaSpots() 筛选出的 4 个广场地形,每行左侧地形名 13sp 粗体 + desc 11sp 次级文字(maxLines2),右侧 crowdLabel 人气标签 10sp 荧光橙红字粗体(如江滩 skaters=96 显示「卷王聚集地」)。

8.2 滑板场 parkContent:暗黑渐变 banner + 双列瀑布卡片

滑板场 Tab 由两部分组成:

  1. 免费专业场 bannerangle:135 暗黑渐变 #26262C→#FF5A36(从深灰到荧光橙红),标题「🏟️ 免费专业场 · 道具全览」15sp 粗体白字,副标题「全城7个专业滑板场 · 3个通宵亮灯」11sp #FFB3A0 淡橙字。
  2. 双列瀑布卡片Flex wrap justifyContent:SpaceBetween 双列布局,parkSpots() 筛选出 3 个滑板场(光谷滑板公园/麓谷室内滑板馆/西岸滑板公园),每个卡片 width:48.5%,包含:fee 标签(feeBadgeColor 映射色底白字)+ ⭐评分 11sp 粗体金字、地形名 15sp 粗体、城市 11sp 次级文字、desc 11sp 次级文字(maxLines3)、照明·地面材质 10sp 次级文字。

8.3 U池 rampContent:暗黑大卡列表

U池 Tab 由标题 + 暗黑大卡列表组成:

  1. 标题:「🌊 大U池 · 高手主场」15sp 粗体主文字。
  2. 暗黑大卡列表rampSpots() 筛选出 2 个 U 池地形(梅溪湖大 U 池/首钢极限公园),每个渲染为 #26262C 深灰卡片(darkCard)圆角 16,包含:地形名 17sp 粗体白字 + 难度星级 12sp 荧光橙红粗体、城市·地面材质·收费 11sp #9A9AA4 灰字、desc 12sp #C9C9D2 淡灰字 lineHeight:18、#标签 行(#33262B 深紫红底荧光橙红字,如「#两米大U」「#木质面」「#高手主场」)、⭐评分 12sp 粗体金字 + 人气值 11sp 灰字。U池 Tab 通过深灰卡片底 + 荧光橙红强调,完整营造了「大 U 池高手主场」的硬核氛围。

QQ滑板街式Tab与碗池Tab运行效果

8.4 街式 streetContent:标签云 + 紧凑列表 + 彩蛋点位

街式 Tab 由三部分组成:

  1. 标签云Flex wrap justifyContent:Center 8 个街式地形标签(#台阶/#扶手/#斜台/#长椅/#花坛边/#路牙/#金字塔台/#浪墙),#FFE9E3 浅橙红底 #C93A1D 深橙红字,居中排列形成标签云。
  2. 紧凑列表streetSpots() 筛选出 2 个街式地形(StreetWare 街区公园/琶洲街式公园),每行左侧 🚧 路障图标 24sp,中间地形名·城市 13sp 粗体 + 难度·地面材质·照明 11sp 次级文字,右侧 ⭐评分 12sp 粗体金字。
  3. 街式彩蛋点位:遍历 SPOTS,筛选 type === '广场' && skaters >= 90 的广场地形(江滩极限广场/珠江新城广场带),渲染为「🔥 街式彩蛋点位:地形名」11sp 白字粗体,#1B1B1F 街头黑底圆角 14。彩蛋点位是街式 Tab 的特色内容——告诉滑手哪些广场也可以玩街式,增加探索乐趣。

8.5 碗池 bowlContent:招式时间轴 + 碗池列表

碗池 Tab 由三部分组成:

  1. 标题:「🥣 碗池进阶之路」15sp 粗体主文字。
  2. 招式时间轴:遍历 TRICKS,筛选 direction === '碗池' || direction === 'U池' 的招式(Air/Rock Slide),每行左侧是 30x30 圆形 #FF5A36 荧光橙红底序号(白字粗体),右侧是 icon+招式名·等级 14sp 粗体 + 方向 10sp 次级文字 + 要领 11sp 次级文字。圆形序号纵向排列形成时间轴视觉,适合碗池的「进阶之路」主题。
  3. 碗池列表bowlSpots() 筛选出 2 个碗池地形(汉口江滩碗池/大学城碗池群),每个渲染为白底圆角 14 卡片,包含:🥣 地形名 14sp 粗体、城市·难度·收费 11sp 次级文字、desc 11sp 次级文字。

8.6 平花 flatContent:三列招式格 + 平花点位 + 拍视频按钮

平花 Tab 由四部分组成:

  1. 标题:「✨ 平花招式库」15sp 粗体主文字。
  2. 三列招式格Flex wrap justifyContent:SpaceBetween 三列布局,TRICKS 全部 9 个招式,每个格子 width:31%,包含:icon 26sp、招式名 13sp 粗体、等级标签 10sp(高手 #C0392B 红/进阶 #FF5A36 荧光橙红/入门 #8FBF7F 草绿,#FFE9E3 浅橙红底)。三列格子适合平花招式的「紧凑展示」。
  3. 平花点位列表flatSpots() 筛选出 1 个平花地形(永嘉路平花角),每行 ✨ 地形名 13sp 粗体 + 城市·地面材质 11sp 次级文字。
  4. 拍视频按钮:「📹 拍下你的新招」13sp 白字粗体,#FF5A36 荧光橙红底圆角 20,点击打开视频弹窗。

QQ滑板平花Tab与视频Tab运行效果

九、视频 Tab:今日滑板视频 + 发布 + 删除 + 看地形

视频 Tab videoContent 由标题栏 + 8 条视频卡片组成:

  1. 标题栏:左侧「🔥 今日滑板视频」16sp 粗体,右侧「发布视频 +」12sp 白字粗体(#FF5A36 荧光橙红底圆角 14),点击打开视频弹窗。
  2. 视频卡片列表:8 条视频,每个卡片包含:
    • 封面区:80x80 #26262C 深灰卡片底圆角 14,cover Emoji 图标 34sp + 时长标签(#99000000 半透明黑底白字 9sp)。
    • 信息区:标题 13sp 粗体(maxLines1)、@skater·trick 11sp 荧光橙红字、📍spot 10sp 次级文字、❤点赞数 11sp 红字 + 💬评论数 11sp 次级文字。
    • 操作按钮:「删除」#C0392B 红描边按钮(→删除弹窗)+ 「看地形」#FF5A36 荧光橙红描边按钮(→详情弹窗),右对齐。

视频 Tab 通过封面区+信息区+操作区的三段式布局,完整展示滑板视频的核心信息,通过删除和看地形按钮提供视频管理与地形跳转功能,是滑板社交的内容核心区。

十、装备 Tab:装备库 + 晒新装备 + 保养小贴士

装备 Tab gearContent 由标题栏 + 8 件装备列表 + 保养小贴士组成:

  1. 标题栏:左侧「🧢 我的装备库」16sp 粗体,右侧「晒新装备 +」12sp 白字粗体(#1B1B1F 街头黑底圆角 14),整行点击打开装备弹窗。
  2. 装备列表:8 件装备,每行左侧 icon 26sp,中间装备名·品牌 13sp 粗体 + 规格 11sp 次级文字,右侧 ¥价格 13sp 粗体 #C0392B 红字 + 状态 10sp(正在服役 #5B8C5A 草绿字/其他 #9A9AA4 灰字)。
  3. 装备保养小贴士:标题「🛠️ 装备保养小贴士」13sp 粗体,下方 4 条·列表(轴承每两周清灰上油/板面浸水立即擦干/轮子磨损及时换位/砂纸脏了用刷子干刷),11sp 次级文字。

装备 Tab 通过装备列表管理每件装备的品牌规格价格与服役状态,通过保养小贴士提供装备维护知识,是滑板装备管理的实用工具。

QQ滑板装备Tab运行效果

十一、我的 Tab:个人信息 + 四列统计 + 招式进度墙 + 常驻点位

我的 Tab mineContent 由四部分组成:

  1. 个人信息卡:白底圆角 18,左侧 🛹 滑板图标 46sp,右侧「板龄三年的阿浪」18sp 粗体 + 「ID: 73210 · 主玩街式 · Tre Flip 练习中」11sp 次级文字。「Tre Flip 练习中」是滑板圈黑话,Tre Flip(360 翻板)是进阶招式,说明玩家当前正在练习的招式。
  2. 四列统计卡:白底圆角 16,等宽四列——「168 滑行天数」#FF5A36 荧光橙红字、「23 掌握招式」#1B1B1F 街头黑字、「9 摔伤次数」#C9862B 金字、「486h 累计板时」#5B8C5A 草绿字。「摔伤次数」是滑板圈特色统计项,充满硬核幽默感。
  3. 招式进度墙:标题「🔥 招式进度墙」,Flex wrap 展示 TRICKS 全部 9 个招式,每个为「icon + 招式名」11sp,高手级招式用 #9A9AA4 灰字 #F2F2F4 灰底(未掌握),其他用 #C93A1D 深橙红字 #FFE9E3 浅橙红底(已掌握)。招式进度墙直观展示玩家的招式掌握情况。
  4. 常驻点位:标题「📍 我的常驻点位」,遍历 SPOTS 筛选 skaters >= 94 的高人气地形(江滩极限广场/光谷滑板公园/西岸滑板公园/首钢极限公园),每个为「🔥 地形名 · 城市」11sp 白字,#1B1B1F 街头黑底圆角 12。

QQ滑板我的Tab运行效果

十二、4 个模态弹窗:新增/新增/删除/详情四态闭环

应用实现了 4 个模态弹窗,覆盖发布视频(新增)、晒新装备(新增)、删除视频(删除)、地形详情(查询)四种交互形态,每个弹窗都有专属的头色与表单结构。

12.1 发布视频 videoModal:街头黑到深橙红渐变头 + 招式/地点/风格/摔次

视频弹窗 width:90% height:74% 圆角 20,顶部是 angle:120 街头黑到深橙红渐变头 #1B1B1F→#C93A1D,标题「🎬 发布滑板视频」17sp 粗体白字 + 「让全世界看到你的招」11sp #FFB3A0 淡橙字。

滚动内容区包含:

  • 本条招式Flex wrap 8 个选项(Ollie/Kickflip/Tre Flip/50-50/Carve/Air/荡板/连招),选中态荧光橙红底白字,非选中 #FFE9E3 浅橙红底深橙红字,点击切换 videoTrickIndex
  • 拍摄地点Flex wrap 15 个地形选项,选中态街头黑底白字,非选中 #F2F2F4 灰底深字。
  • 剪辑风格Row 4 个选项(原速/慢动作/鱼眼/第一视角),选中态 #26262C 深灰卡片底白字,非选中 #F2F2F4 灰底灰字,点击切换 videoClipStyleIndex
  • 摔了几次才成Row 4 个选项(一次过/摔了3次/摔了10次/数不清),#FFE9E3 浅橙红底深橙红字。这是滑板视频弹窗的特色字段——记录摔了多少次才成功,充满滑板文化的硬核幽默。
  • 操作按钮:「取消」#F2F2F4 灰底灰字 + 「发布」荧光橙红底白字粗体,均点击关闭弹窗。

12.2 晒新装备 gearModal:浅橙红头 + 类型/价格/成色/用法

装备弹窗 width:90% height:70% 圆角 20,顶部是纯浅橙红 #FFE9E3(深字,是所有弹窗中唯一用浅色头的),标题「🧢 晒新装备」17sp 粗体深字 + 「入坑证据提交处」11sp 次级文字。

滚动内容区包含:

  • 装备类型Flex wrap 7 个选项(整板/板面/轮子/轴承/护具/板鞋/其他),选中态荧光橙红底白字,非选中 #FFE9E3 浅橙红底深橙红字。
  • 入手价格档Row 4 个选项(百元内/一百到五百/五百到一千/千元以上),选中态街头黑底白字,非选中 #F2F2F4 灰底深字。
  • 成色状态Flex wrap 4 个选项(全新未拆/九成新/战斗成色/退役收藏),选中态 #26262C 深灰卡片底白字,非选中 #F2F2F4 灰底灰字。「战斗成色」是滑板圈黑话,形容装备用得很旧但还在战斗。
  • 打算怎么用Row 两个选项——「天天滑」#E8F4E7 浅绿底草绿字 + 「舍不得用」#FFF6DE 浅金底金字。
  • 操作按钮:「取消」灰底灰字 + 「晒出来」街头黑底白字粗体。

12.3 删除视频 deleteVideoModal:🗑️ 警告小卡

删除弹窗是 4 个弹窗中最小的一个,width:78% 白底圆角 20,居中显示:

  • 🗑️ 垃圾桶图标 40sp
  • 「删除这条视频?」16sp 粗体主文字
  • 「删除后点赞和评论数据将一并清除,且无法恢复。发布超过48小时的视频删除不影响创作者等级。」12sp 次级文字(lineHeight:18,居中)
  • 操作按钮:「再想想」#F2F2F4 灰底灰字 + 「删除」#C0392B 红底白字粗体,均点击关闭弹窗。

删除弹窗通过 🗑️ 图标 + 红色确认按钮 + 详细后果说明(点赞评论清除/无法恢复/超48小时不影响等级),提醒用户操作不可逆,符合删除类操作的交互规范。

12.4 地形详情 spotDetailModal:街头黑到深橙红渐变头 + 标签/统计/点评/发视频+收藏

详情弹窗 width:90% height:76% 圆角 20,是 4 个弹窗中最高的一个,内容最丰富。顶部是 angle:135 街头黑到深橙红渐变头 #1B1B1F→#C93A1D

  • 顶部行:左侧 🛹 滑板图标 34sp,右侧「✕」关闭按钮(#4A4A54 深灰底圆角 14),点击关闭弹窗。
  • 地形名 20sp 粗体白字(通过 detailSpotName() 查找)。
  • 城市·类型·地面材质 12sp #FFB3A0 淡橙字(通过 detailSpotMeta() 查找)。

滚动内容区包含:

  • 地形描述detailSpotDesc() 返回的 desc 文本,13sp 主文字 lineHeight:20。
  • 地形标签:标题 + Flex wrap 渲染 detailSpotTags() 返回的标签数组,每个标签为「#标签」12sp 粗体 #C93A1D 深橙红字 + #FFE9E3 浅橙红底。
  • 三列统计卡#F7F7F9 浅灰底圆角 14,等宽三列——「⭐评分 滑手评分」#C9862B 金字粗体、「收费(免费草绿/其他金)」、「人气值 荧光橙红」。
  • 滑手点评:标题 + ForEach(SPOT_REVIEWS) 渲染 3 条点评,每条为 #F7F7F9 浅灰底圆角 12 卡片,包含用户名 + 时间(右对齐)、星号 Emoji、点评文字 12sp 次级文字 lineHeight:18。评价用户名「每天滑两小时」「摔了但值得」「板龄三年的菜鸡」充满滑板圈梗文化。
  • 操作按钮:「发视频打卡」荧光橙红底白字粗体(点击关闭详情 + 打开视频弹窗,实现详情→发视频的流畅跳转)+ 「收藏点位」#F2F2F4 灰底深字粗体。

QQ滑板弹窗运行效果

12.5 detailSpot 系列方法:8 个查找方法

详情弹窗通过 selectedSpotIdSPOTS 数组中查找对应地形,定义了 8 个方法:detailSpotName()detailSpotMeta()(返回 city·type·surface)、detailSpotDesc()detailSpotRating()detailSpotFee()detailSpotLight()detailSpotSkaters()detailSpotTags()。每个方法都通过 for...of 遍历 SPOTS 查找匹配 id 的地形,再返回对应字段,若未找到则返回默认值(空字符串/0/空数组)。

十三、特性对比表

特性维度 QQ滑板·滑起来实现
主题风格 街头黑 #1B1B1F + 荧光橙红 #FF5A36 + 水泥浅灰 #F2F2F4 潮酷街头风
导航架构 底部 4 Tab(地形/视频/装备/我的)+ 顶部 6 Tab(广场/滑板场/U池/街式/碗池/平花),顶部 Tab 仅地形模块显示,6 Tab 等宽 layoutWeight(1)
数据模型 8 个 interface(ColorPalette/TabItem/ParticleItem/SpotItem/VideoItem/GearItem/TrickItem/SpotReview),SpotItem 含 surface/light 特色字段,TrickItem 含 level/direction/tip
业务数据量 15 地形 + 8 视频 + 8 装备 + 9 招式 + 3 点评 + 7 人气柱状图
工具函数 4 个(difficultyBadge/feeBadgeColor/crowdLabel/crowdBarHeight)
筛选函数 6 个(plazaSpots/parkSpots/rampSpots/streetSpots/bowlSpots/flatSpots)
粒子系统 14 粒子,🛹⚡🔥✨💫🌪️ 六图标循环,独立 speed 0.35~0.83,setInterval 130ms,向下飘动(y+speed,模拟滑板跃下/火焰拖出/旋风卷起)+ 顶部循环,百分比坐标
数据可视化 广场 Tab 本周各点位人气值双色柱状图(7 点位,crowdBarHeight n*1.05,idx%2 荧光橙红/街头黑双色交替,height190 底部对齐)
场景差异化 6 大顶部 Tab 完全不同布局:广场(横滑大卡+人气双色柱状图+列表)/滑板场(暗黑渐变banner+双列瀑布)/U池(暗黑大卡列表深灰底)/街式(标签云+紧凑列表+彩蛋点位)/碗池(招式时间轴+碗池列表)/平花(三列招式格+平花点位+拍视频按钮)
模态弹窗 4 个:发布视频(街头黑到深橙红渐变头,招式/地点/剪辑风格/摔了几次才成特色字段)/晒新装备(浅橙红头,唯一浅色头,类型/价格/成色战斗成色/用法天天滑舍不得用)/删除视频(🗑️红警告小卡,点赞评论清除/超48小时不影响等级)/地形详情(街头黑到深橙红渐变头,标签/三列统计/点评,可跳转发视频+收藏)
状态变量 18 个 @State + 1 个 private timerId
生命周期 aboutToAppear 构建粒子+启动定时器,aboutToDisappear clearInterval
头部特色 街头黑到荧光橙红渐变 angle:160(最具冲击力头部渐变)+ Skate or Die 口号 + 今日滑手2140深灰卡片
底部 Tab 特色 街头黑 #1B1B1F(所有应用中唯一底部导航用深色底),激活深橙红字,shadow offsetY:-3
顶部 Tab 特色 6 Tab 等宽,激活态荧光橙红圆角下划线(Divider borderRadius2)
分类色系统 difficultyBadge 4 色(难度星级映射,红/荧光橙红/金/草绿)+ feeBadgeColor 2 色(免费草绿/收费金)+ 招式等级 3 色(高手红/进阶荧光橙红/入门草绿)
滑板圈文化梗 Skate or Die/卷王聚集地/板龄三年的菜鸡/摔了但值得/战斗成色/Tre Flip练习中/摔伤次数统计/摔了几次才成/街式彩蛋点位
特色数据字段 SpotItem.surface(地面材质)+ SpotItem.light(照明情况)+ TrickItem(9招式含level/direction/tip)
弹窗跳转 地形详情「发视频打卡」→关闭详情+打开视频弹窗

十四、完整代码

应用完整源码位于 1094.ets,总计约 1500 行,包含 8 个 interface、10 个常量数组/对象、4 个工具函数、6 个筛选函数、1 个 @Entry @Component struct SkatePage 主组件(18 个 @State + 2 个生命周期方法 + 19 个 @Builder 方法 + 8 个 detailSpot 查找方法 + build 方法)。

核心代码结构如下:

// 8 个 interface 定义
interface ColorPalette { ... }  // 含 dark/darkCard 特色字段
interface TabItem { ... }
interface ParticleItem { ... }
interface SpotItem { ... }  // 含 surface/light 特色字段
interface VideoItem { ... }
interface GearItem { ... }
interface TrickItem { ... }  // 含 level/direction/tip
interface SpotReview { ... }

// 常量定义
const SKATE_COLORS: ColorPalette = { ... }
const BOTTOM_TABS: TabItem[] = [ ... ]
const TOP_TABS: TabItem[] = [ ... ]  // 6 个 Tab
const SPOTS: SpotItem[] = [ ... ]  // 15 个地形
const VIDEOS: VideoItem[] = [ ... ]  // 8 条视频
const GEARS: GearItem[] = [ ... ]  // 8 件装备
const TRICKS: TrickItem[] = [ ... ]  // 9 个招式
const SPOT_REVIEWS: SpotReview[] = [ ... ]  // 3 条点评
const CROWD_BARS: number[] = [96, 78, 85, 94, 82, 71, 91]
const CROWD_LABELS: string[] = ['江滩', '中山', '汉口碗', '光谷', '街Ware', '麓谷', '大学城']

// 4 个工具函数
function difficultyBadge(diff: string): string { ... }
function feeBadgeColor(fee: string): string { ... }
function crowdLabel(n: number): string { ... }
function crowdBarHeight(n: number): string { ... }

// 6 个筛选函数
function plazaSpots(): SpotItem[] { ... }
function parkSpots(): SpotItem[] { ... }
function rampSpots(): SpotItem[] { ... }
function streetSpots(): SpotItem[] { ... }
function bowlSpots(): SpotItem[] { ... }
function flatSpots(): SpotItem[] { ... }

// 主组件
@Entry
@Component
struct SkatePage {
  // 18 个 @State + timerId
  @State currentBottomTab: number = 0
  @State currentTopTab: number = 0
  @State showVideoModal: boolean = false
  @State showGearModal: boolean = false
  @State showDeleteModal: boolean = false
  @State showDetailModal: boolean = false
  @State selectedSpotId: number = 0
  @State deleteVideoId: number = 0
  @State videoTrickIndex: number = 0
  @State videoSpotIndex: number = 0
  @State videoClipStyleIndex: number = 0
  @State gearTypeIndex: number = 0
  @State gearPriceIndex: number = 0
  @State gearConditionIndex: number = 0
  @State particles: ParticleItem[] = []
  private timerId: number = -1

  // 生命周期
  aboutToAppear(): void { ... }
  aboutToDisappear(): void { ... }

  // 粒子方法
  buildParticles(): ParticleItem[] { ... }
  driftParticles(): void { ... }

  // 8 个 detailSpot 查找方法
  detailSpotName(): string { ... }
  detailSpotMeta(): string { ... }
  detailSpotDesc(): string { ... }
  detailSpotRating(): string { ... }
  detailSpotFee(): string { ... }
  detailSpotLight(): string { ... }
  detailSpotSkaters(): number { ... }
  detailSpotTags(): string[] { ... }

  // 19 个 @Builder 方法
  @Builder headerBuilder() { ... }  // 街头黑到荧光橙红渐变
  @Builder topTabsBuilder() { ... }  // 6 Tab 等宽
  @Builder bottomTabsBuilder() { ... }  // 街头黑底(唯一深色底底部导航)
  @Builder plazaContent() { ... }  // 横滑大卡+人气双色柱状图
  @Builder parkContent() { ... }  // 暗黑渐变banner+双列瀑布
  @Builder rampContent() { ... }  // 暗黑大卡列表
  @Builder streetContent() { ... }  // 标签云+紧凑列表+彩蛋点位
  @Builder bowlContent() { ... }  // 招式时间轴+碗池列表
  @Builder flatContent() { ... }  // 三列招式格+平花点位
  @Builder videoContent() { ... }
  @Builder gearContent() { ... }
  @Builder mineContent() { ... }
  @Builder videoModal() { ... }
  @Builder gearModal() { ... }
  @Builder deleteVideoModal() { ... }
  @Builder spotDetailModal() { ... }

  // 根布局
  build() {
    Stack() {
      Column() {  // 主界面
        this.headerBuilder()
        if (this.currentBottomTab === 0) this.topTabsBuilder()
        Scroll() { Column() { ... 内容分发 ... } }
        this.bottomTabsBuilder()
      }
      ForEach(this.particles, ...)  // 粒子层(向下飘动)
      if (this.showVideoModal) { ... }  // 4 个弹窗层
      if (this.showGearModal) { ... }
      if (this.showDeleteModal) { ... }
      if (this.showDetailModal) { ... }
    }
  }
}

1094.ets 放入 HarmonyOS 项目的 entry/src/main/ets/pages/ 目录下,在 main_pages.json 中注册路由,即可在 DevEco Studio 中预览运行。

十五、开发环境搭建:DevEco Studio + API 24

本应用基于 HarmonyOS NEXT(API 24)开发,使用 ArkTS 声明式 UI 框架。以下是完整的开发环境搭建步骤。

15.1 安装 DevEco Studio

从华为开发者联盟官网下载 DevEco Studio 安装包,双击运行安装程序。安装欢迎界面如下,点击「Next」继续。

DevEco Studio安装欢迎界面

15.2 选择安装位置

在安装路径选择界面,建议选择空间充足的磁盘(建议剩余空间 20GB 以上),避免使用中文路径或含空格的路径。点击「Next」继续。

选择DevEco Studio安装路径

15.3 配置安装选项

在安装选项配置界面,勾选「Create Desktop Shortcut」(创建桌面快捷方式)、「Add to PATH」(添加到环境变量)等选项,方便后续命令行调用。点击「Next」继续。

DevEco Studio安装选项配置

15.4 新建项目:选择 Empty Ability 模板

安装完成后启动 DevEco Studio,点击「Create Project」新建项目。在模板选择界面,选择「Empty Ability」(空 Ability)模板,这是最基础的 ArkTS 应用模板,适合从零构建自定义 UI。点击「Next」继续。

选择Empty Ability模板

15.5 配置项目信息:API 24

在项目配置界面,填写项目名称(如 QQSkate)、包名(如 com.example.qqskate),Compatible SDK 选择 6.1.1(24)(即 API 24),Save location 选择项目保存路径。确认信息无误后点击「Finish」创建项目。

配置项目信息与API 24

15.6 导入源码与运行

项目创建完成后,将 1094.ets 文件复制到 entry/src/main/ets/pages/ 目录下,打开 entry/src/main/resources/base/profile/main_pages.json,在 src 数组中添加 "pages/1094" 路由注册。

在 DevEco Studio 顶部工具栏选择 Previewer(预览器)或连接真机/模拟器,点击运行按钮即可看到「QQ滑板·滑起来」应用的完整运行效果。可以切换底部 4 Tab、顶部 6 Tab,点击地形卡片查看详情、发布视频填写表单、在装备 Tab 晒新装备、在视频 Tab 删除视频,体验完整的滑板社交闭环。

十六、总结

「QQ滑板·滑起来」是一个以滑板为主题的完整移动端社区应用,基于 HarmonyOS NEXT(API 24)ArkTS 声明式 UI 框架构建,单文件 1094.ets 约 1500 行代码实现了全部功能。

应用的核心亮点包括:

  1. 街头黑 + 荧光橙红潮酷街头风视觉体系:11 色基础调色板(含 dark 街头黑和 darkCard 深灰卡片,比常规多 2 色)+ difficultyBadge 4 色难度映射(红/荧光橙红/金/草绿)+ feeBadgeColor 2 色收费映射 + 招式等级 3 色,通过色彩快速区分地形难度与收费。头部使用 angle:160 街头黑到荧光橙红渐变(从黑到橙红的渐变模拟滑板从阴影冲向阳光,是所有应用中最具冲击力的头部渐变)+ Skate or Die 经典口号 + 今日滑手 2140 深灰卡片。底部 Tab 用街头黑底是所有应用中唯一底部导航栏使用深色底的,营造滑板鞋踩在黑色磨砂板面上的潮酷质感。
  2. 双层导航 + 6 大地形差异化布局:底部 4 Tab(地形/视频/装备/我的)+ 顶部 6 Tab(广场/滑板场/U池/街式/碗池/平花),6 个地形采用完全不同的布局风格(横滑大卡+人气双色柱状图/暗黑渐变 banner+双列瀑布/暗黑大卡列表/标签云+紧凑列表+彩蛋点位/招式时间轴+碗池列表/三列招式格+平花点位),是地形差异化设计的典范。顶部 Tab 激活态使用荧光橙红圆角下划线(Divider borderRadius2),是独特的视觉细节。
  3. 14 粒子独立速度向下飘动动画:🛹⚡🔥✨💫🌪️ 六图标循环,每个粒子拥有独立 speed 0.35~0.83(近期应用中较快速度),向下飘动(y+speed,模拟滑板从台阶跃下落地、火焰从板尾拖出下落、旋风从轮下卷起向下扩散的街头运动意象,与常规上升粒子形成鲜明反差)+ 顶部循环,百分比坐标适配多屏幕,setInterval 130ms 驱动(配合较快速度模拟滑板运动的速度感与街头节奏感),aboutToAppear/aboutToDisappear 生命周期管理。向下飘动是本应用粒子系统最具特色的设计决策。
  4. 人气双色柱状图数据可视化:广场 Tab 内嵌本周各点位人气值双色柱状图(7 点位,crowdBarHeight 换算高度 n*1.05,idx%2===0 荧光橙红 #FF5A36 其他街头黑 #1B1B1F 双色交替,江滩 96 最高形成卷王聚集地可视化,底部对齐 height190)。双色交替柱状图是本应用数据可视化的特色,形成强烈的街头视觉冲击。
  5. 4 个模态弹窗闭环:发布视频(街头黑到深橙红渐变头,招式/拍摄地点/剪辑风格/摔了几次才成特色字段,记录摔了多少次才成功充满滑板文化硬核幽默)、晒新装备(浅橙红头,是所有弹窗中唯一用浅色头的,类型/价格档/成色含战斗成色黑话/用法天天滑舍不得用)、删除视频(🗑️红警告小卡,强调点赞评论清除/无法恢复/超48小时不影响创作者等级)、地形详情(街头黑到深橙红渐变头,描述/地形标签/三列统计含人气值/滑手点评充满滑板圈梗文化,可跳转发视频+收藏),覆盖新增/新增/删除/查询四态。
  6. 强类型数据模型 + 特色字段 + 招式库 + 工具函数 + 筛选函数三层架构:8 个 interface 约束所有数据结构,SpotItem 含 surface(地面材质,滑板玩家在意地面顺滑度)和 light(照明情况,夜滑玩家关注亮灯时间)两个特色字段,TrickItem 含 9 个招式(荡板/Ollie/Shove-it/Manual/50-50/Kickflip/Tre Flip/Air/Rock Slide,每个含 level/direction/tip),15 地形 + 8 视频 + 8 装备 + 9 招式 + 3 点评的丰富预置数据,4 个工具函数(difficultyBadge/feeBadgeColor/crowdLabel/crowdBarHeight)负责视觉映射,6 个筛选函数负责数据分发,detailSpot 系列 8 个查找方法实现详情弹窗的数据驱动。三层架构让模板简洁、逻辑清晰。
  7. 滑板圈文化梗贯穿全应用:Skate or Die 经典口号/卷王聚集地/板龄三年的菜鸡/摔了但值得/战斗成色/Tre Flip 练习中/摔伤次数统计/摔了几次才成/街式彩蛋点位/每天滑两小时,让应用充满滑板社区的文化认同感。街式彩蛋点位(告诉滑手哪些广场也可以玩街式)增加探索乐趣,是本应用的特色内容设计。

QQ滑板·滑起来整体运行效果

对于希望学习 HarmonyOS ArkTS 声明式 UI 开发的读者,本应用提供了一个完整的参考范本:如何通过 @State 驱动状态更新、如何用 @Builder 拆分复杂布局、如何用 Stack 分层实现粒子与弹窗、如何用 setInterval + 生命周期实现动画(特别是如何通过方向反转与速度变化模拟不同场景的运动意象)、如何用 interface + 特色字段 + 常量数组 + 工具函数 + 筛选函数构建分层数据层、如何通过双色柱状图实现数据可视化、如何通过底部深色底导航营造主题氛围、如何通过 6 Tab 差异化布局展示不同地形类型。将源码导入 DevEco Studio(API 24)即可直接运行预览,在此基础上可以扩展更多地形数据、接入真实后端 API、增加地图定位与导航、接入视频上传与播放功能、增加招式教学与 AI 纠错功能,打造一个真正可用的滑板社交平台。

四轮乘风,街头为王。愿每一个热爱滑板的人,都能在 Ollie 与 Kickflip 之间找到属于自己的那片街头,也能在代码与板面之间找到属于自己的那份速度与激情。

标签: HarmonyOS · ArkTS · API 24

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐