HarmonyOS 引导页项目实战
新增引导步骤:在下创建页面,并在注册,更新前一页的。自定义主题:在各页面使用动态切换颜色。表单扩展:在新增输入字段并在saveData()中持久化。
HarmonyOS 引导页项目实战:一步步完成从零到可运行
本文面向初学者与一线开发,带你从一个空的 Entry 工程开始,按步骤实现“首次启动进入引导页、完成后进入主页面、支持主题持久化与用户数据存储”的完整功能。跟着做即可复现本项目功能。
你将实现的效果
- 首次启动:自动进入三步引导页(欢迎 → 数据收集 → 完成)。
- 完成引导:记录状态,后续启动直接进入主页面。
- 数据保存:表单信息使用 Preferences 持久化。
- 主题支持:深色/浅色模式全局生效并持久化。



环境准备
- DevEco Studio(建议最新稳定版)
- HarmonyOS SDK(与项目模板匹配版本)
- 能运行手机/模拟器
步骤 0:创建或打开工程
- 使用 DevEco Studio 创建默认 Entry 工程,包结构保持默认。
- 下文以模块名
entry、主页面pages/Index为例。
步骤 1:建立目录结构
在 entry/src/main/ets 下创建目录:
models/
utils/
pages/
└─ onboarding/
步骤 2:注册页面路由(必做)
编辑文件:entry/src/main/resources/base/profile/main_pages.json
确保包含以下页面路径(缺失将导致“can’t find this page … path”错误):
{
"src": [
"pages/Index",
"pages/onboarding/WelcomeGuidePage",
"pages/onboarding/DataCollectionPage",
"pages/onboarding/CompletionPage"
]
}
步骤 3:应用入口 EntryAbility
文件:entry/src/main/ets/entryability/EntryAbility.ets
要点:
- 在
onCreate中初始化AppStorage的全局主题键app_is_dark_mode。 - 在
onWindowStageCreate中loadContent('pages/Index')。
代码示例(片段):
AppStorage.setOrCreate('app_is_dark_mode', false);
windowStage.loadContent('pages/Index');
步骤 4:创建主题模型 ThemeModel
文件:entry/src/main/ets/models/ThemeModel.ets
职责:
- 从 Preferences 读取/保存
is_dark_mode。 - 同步到
AppStorage('app_is_dark_mode'),供全局订阅。
完整代码:
/**
* 主题模型 - 管理应用主题
*/
import { preferences } from '@kit.ArkData'
import { common } from '@kit.AbilityKit'
export class ThemeModel {
private isDarkMode: boolean = false
private preferencesInstance: preferences.Preferences | null = null
async loadThemeSettings(): Promise<void> {
try {
const context = getContext() as common.UIAbilityContext
this.preferencesInstance = await preferences.getPreferences(context, 'theme_preferences')
const saved = await this.preferencesInstance.get('is_dark_mode', false) as boolean
this.isDarkMode = saved
AppStorage.setOrCreate('app_is_dark_mode', this.isDarkMode)
} catch (error) {
console.error('ThemeModel', '加载主题设置失败:', error)
}
}
async toggleTheme(): Promise<void> {
try {
this.isDarkMode = !this.isDarkMode
AppStorage.setOrCreate('app_is_dark_mode', this.isDarkMode)
if (this.preferencesInstance) {
await this.preferencesInstance.put('is_dark_mode', this.isDarkMode)
await this.preferencesInstance.flush()
}
} catch (error) {
console.error('ThemeModel', '切换主题失败:', error)
}
}
getIsDarkMode(): boolean {
return this.isDarkMode
}
}
步骤 5:创建引导状态管理 OnboardingManager
文件:entry/src/main/ets/utils/OnboardingManager.ets
职责:
- 使用 Preferences 记录是否完成引导。
- 封装单例,提供
initialize/hasShown/mark/reset。
完整代码:
/** 引导页管理器 */
import { preferences } from '@kit.ArkData'
import { common } from '@kit.AbilityKit'
const PREFERENCES_NAME = 'onboarding_preferences'
const KEY_HAS_SHOWN_ONBOARDING = 'has_shown_onboarding'
export class OnboardingManager {
private static instance: OnboardingManager | null = null
private preferencesInstance: preferences.Preferences | null = null
private isInitialized: boolean = false
private constructor() {}
static getInstance(): OnboardingManager {
if (!OnboardingManager.instance) OnboardingManager.instance = new OnboardingManager()
return OnboardingManager.instance
}
async initialize(context: common.UIAbilityContext): Promise<void> {
if (this.isInitialized) return
this.preferencesInstance = await preferences.getPreferences(context, PREFERENCES_NAME)
this.isInitialized = true
console.info('OnboardingManager', '初始化成功')
}
async hasShownOnboarding(): Promise<boolean> {
if (!this.preferencesInstance) return false
try {
const hasShown = await this.preferencesInstance.get(KEY_HAS_SHOWN_ONBOARDING, false) as boolean
console.info('OnboardingManager', `引导页显示状态: ${hasShown}`)
return hasShown
} catch (e) {
console.error('OnboardingManager', '读取引导页状态失败:', e)
return false
}
}
async markOnboardingAsShown(): Promise<void> {
if (!this.preferencesInstance) return
await this.preferencesInstance.put(KEY_HAS_SHOWN_ONBOARDING, true)
await this.preferencesInstance.flush()
}
async resetOnboardingStatus(): Promise<void> {
if (!this.preferencesInstance) return
await this.preferencesInstance.put(KEY_HAS_SHOWN_ONBOARDING, false)
await this.preferencesInstance.flush()
}
}
步骤 6:创建引导页 - WelcomeGuidePage
文件:entry/src/main/ets/pages/onboarding/WelcomeGuidePage.ets
要点:
@Entry @Component页面。- 顶部安全区、主题适配、进度指示、跳过与下一步。
关键片段:
@Entry
@Component
struct WelcomeGuidePage {
@State themeModel: ThemeModel = new ThemeModel()
@StorageProp('app_is_dark_mode') isDarkMode: boolean = false
async aboutToAppear() { await this.themeModel.loadThemeSettings() }
build() {
// ... UI,下一步:router.pushUrl({ url: 'pages/onboarding/DataCollectionPage' })
}
}
完整实现可参考本仓库同名文件。
步骤 7:创建引导页 - DataCollectionPage
文件:entry/src/main/ets/pages/onboarding/DataCollectionPage.ets
要点:
- 表单输入 + 选项选择。
- 校验后保存到 Preferences。
- 下一步跳转到完成页。
关键片段:
private async saveData() {
const context = getContext(this) as common.UIAbilityContext
const prefs = await preferences.getPreferences(context, 'onboarding_data')
await prefs.put('user_name', this.userName)
await prefs.put('selected_option', this.selectedOption)
await prefs.flush()
}
步骤 8:创建引导页 - CompletionPage
文件:entry/src/main/ets/pages/onboarding/CompletionPage.ets
要点:
- 点击“开始使用”时,调用
OnboardingManager.markOnboardingAsShown()。 - 跳转回
pages/Index。
关键片段:
const manager = OnboardingManager.getInstance()
await manager.initialize(getContext(this) as common.UIAbilityContext)
await manager.markOnboardingAsShown()
router.replaceUrl({ url: 'pages/Index' })
步骤 9:修改首页 Index.ets(引导决策)
文件:entry/src/main/ets/pages/Index.ets
要点:
aboutToAppear初始化主题并检查引导状态。- 未完成引导 → 延时
replaceUrl到欢迎页。 - 外层容器必须设置背景色,避免白屏。
关键片段:
async aboutToAppear() {
await this.themeModel.loadThemeSettings()
await this.checkOnboardingStatus()
}
setTimeout(() => {
router.replaceUrl({ url: 'pages/onboarding/WelcomeGuidePage' })
}, 100)
Column() { /* ... */ }
.width('100%').height('100%')
.backgroundColor(this.isDarkMode ? '#121212' : '#F5F5F5')
步骤 10:编译与运行
# DevEco Studio
Build > Build App(s)
Run 或 Shift + F10
步骤 11:测试用例
- 首次启动:应自动进入引导页第 1 步。
- 填表完成 → 进入完成页 → 点击“开始使用” → 返回首页。
- 再次启动:应直接进入首页,不再显示引导页。
- 重置状态(可选):
hdc shell pm uninstall <你的包名>
# 或在代码中调用 OnboardingManager.resetOnboardingStatus()
常见问题与排查
- 报错 “can’t find this page … path”
- 确认
main_pages.json已注册所有引导页路径。
- 启动白屏
- 确认首页最外层容器设置了
.backgroundColor(...)。
- 主题不切换
- 确认
EntryAbility.onCreate已初始化AppStorage('app_is_dark_mode')。
- 数据未保存
- 确认
await prefs.flush()已调用。
目录与参考实现
本项目完整实现已包含在以下文件中,可直接对照复制:
entry/src/main/ets/models/ThemeModel.etsentry/src/main/ets/utils/OnboardingManager.etsentry/src/main/ets/pages/Index.etsentry/src/main/ets/pages/onboarding/WelcomeGuidePage.etsentry/src/main/ets/pages/onboarding/DataCollectionPage.etsentry/src/main/ets/pages/onboarding/CompletionPage.etsentry/src/main/resources/base/profile/main_pages.jsonentry/src/main/ets/entryability/EntryAbility.ets
进阶:自定义与扩展
- 新增引导步骤:在
pages/onboarding下创建页面,并在main_pages.json注册,更新前一页的router.pushUrl。 - 自定义主题:在各页面使用
@StorageProp('app_is_dark_mode')动态切换颜色。 - 表单扩展:在
DataCollectionPage新增输入字段并在saveData()中持久化。
结束语
到此,你已经完成了一个可用的 HarmonyOS 引导页系统。从架构、状态管理到页面编排、主题与存储,都具备了可扩展的实践基础。根据业务继续迭代即可上线使用。
源代码
https://gitcode.com/daleishen/onboarding
班级链接
https://developer.huawei.com/consumer/cn/training/classDetail/fd34ff9286174e848d34cde7f512ce22?type=1%3Fha_source%3Dhmosclass&ha_sourceId=89000248
更多推荐

所有评论(0)