ArkTS延安精神学习应用:四版块 + 三组展开状态 + 大事记时间轴
·



一、设计思路
延安精神学习应用采用"概述 → 核心内涵 → 圣地巡礼 → 经典故事 → 大事记"五段式信息架构。每个版块是一组结构化数据,页面用 Scroll + Column 纵向滚动承载全部内容。核心交互是"点击展开"——三组数据(内涵 / 圣地 / 故事)各自独立管理展开状态,互不干扰。
二、数据模型:三种实体 + 一个特色实体
interface SpiritItem { id: number; title: string; content: string; practice: string; }
interface PlaceItem { id: number; name: string; desc: string; }
interface StoryItem { id: number; title: string; content: string; }
interface TimeItem { id: number; year: string; event: string; }
SpiritItem 多一个 practice(现实启示)字段——每个内涵都落到"今天该怎么做",这是思政学习应用的灵魂:历史精神要与当下生活挂钩。
核心内涵四条:
| 内涵 | 对应实践 |
|---|---|
| 坚定正确的政治方向 | 理想信念不动摇,听党话、跟党走 |
| 解放思想、实事求是 | 不唯书、不唯上、只唯实 |
| 全心全意为人民服务 | 人民至上,做群众贴心人 |
| 自力更生、艰苦奋斗 | 苦干实干,拒绝"躺平" |
三、多组展开状态:三个 expandedId 独立管理
页面同时存在三组可展开列表(内涵、圣地、故事),若共用一个 expandedId,会出现"展开圣地时内涵全收起"的串扰。正确做法是每组一个独立状态:
@State expandedCore: number = -1; // 内涵展开
@State expandedPlace: number = -1; // 圣地展开
@State expandedStory: number = -1; // 故事展开
为了消除三个卡片的重复 onClick 逻辑,抽一个通用 toggle:
toggle(id: number, cur: number, set: (v: number) => void): void {
set(cur === id ? -1 : id);
}
注意:ArkTS 不支持直接把
@State字段按引用传递,所以set回调写法是(v: number) => { this.expandedCore = v; }——用闭包捕获 this,绕开"按值传递"的限制。这是 ArkTS 状态管理的常见技巧。
调用方式:
.onClick(() => { this.toggle(item.id, this.expandedCore, (v: number) => { this.expandedCore = v; }); })
四、大事记时间轴:Row 三列布局
特色版块"延安十三年大事记"(1935→1948 共 9 条)用固定宽度时间列 + 节点列 + 内容列实现:
@Builder
timelineView() {
Column() {
ForEach(this.timeline, (t: TimeItem) => {
Row() {
Text(t.year) // 第一列:时间(固定 64 宽)
.fontSize(12).fontWeight(FontWeight.Bold).fontColor('#92400E')
.width(64).textAlign(TextAlign.Center)
Column() { Text('●') } // 第二列:节点圆点
.width(20).alignItems(HorizontalAlign.Center)
Text(t.event) // 第三列:事件(弹性)
.fontSize(13).fontColor('#4B5563')
.layoutWeight(1).textAlign(TextAlign.Start)
}
.width('100%').alignItems(VerticalAlign.Top)
.padding({ top: 8, bottom: 8 })
.border({ width: { bottom: 1 }, color: '#FDE68A' }) // 行分隔线
}, (t: TimeItem) => t.id.toString())
}
.width('100%').padding(14)
.backgroundColor('#FFFBEB').borderRadius(14)
}
要点:
- 固定宽度列(
width(64))+ 弹性列(layoutWeight(1))组合,保证时间列对齐。 alignItems(VerticalAlign.Top)让多行事件文本与时间列顶部对齐。- 分隔线用
border({ width: { bottom: 1 } }),比Divider更简洁。 - 事件较长时,
●节点在第二列水平居中,视觉上是标准时间轴。
五、主题色系统:同一架构三种配色
三个精神页面结构完全一致,仅靠主题色区分气质:
| 应用 | 主色 | 浅色底 | 语义 |
|---|---|---|---|
| 延安 | #B45309 土黄 |
#FEF3C7 |
黄土高原、窑洞 |
| 井冈山 | #047857 山绿 |
#ECFDF5 |
绿色革命摇篮 |
| 西柏坡 | #1D4ED8 蓝 |
#EFF6FF |
解放指挥所 |
配色集中在 sectionTitle、overviewCard、卡片边框等少数位置,改色只动常量——主题化是 UI 复用的最佳实践。
六、技术要点总结
| 技术点 | 实现方式 |
|---|---|
| 多组展开 | 三个独立 expandedId 状态 |
| 通用 toggle | 回调 set 闭包捕获 this |
| 时间轴 | 固定宽列 + 弹性列 + 底部边框分隔 |
| 长页滚动 | Scroll + Column + layoutWeight(1) |
| 主题色 | 主色/浅底两套色值全页复用 |
| 数据驱动 | 加条目不改代码,改数组即改内容 |
"精神学习类"应用模板:概述 + 内涵 + 圣地 + 故事 + 特色版块,五段式信息架构可直接复用到任何革命精神、文化主题的学习应用。
更多推荐


所有评论(0)