欢迎光临
我们一直在努力

【HarmonyOS 6】使用说明功能:浮动按钮、弹窗与偏好设置

功能概述

在热力图页面(HeatmapPage)中,使用说明功能由三部分协同工作:

  • 内嵌式使用说明面板 — 首次进入或开启常驻时,在网格上方展开的引导卡片
  • 浮动帮助按钮 — 面板隐藏后出现在右上角的圆形悬浮按钮
  • AlertDialog 弹窗 — 点击 ? 按钮后弹出的详细帮助对话框
  • 三者通过两个状态变量联动:showGuide(控制面板显隐)和 showGuideAlways(控制是否常驻)。同时利用 PreferencesManager 将用户选择持久化到本地。


    一、状态定义与初始化

    @State showGuide: boolean = false // 是否显示内嵌面板
    @State showGuideAlways: boolean = false // 是否常驻显示

    页面加载时调用 loadGuidePreferences() 从本地偏好读取设置:

    async aboutToAppear(): Promise<void> {
    await this.loadData()
    await this.loadGuidePreferences() // 加载使用说明偏好
    }

    private async loadGuidePreferences(): Promise<void> {
    const hasSeenGuide = await this.preferencesManager.hasSeenGuide()
    this.showGuideAlways = await this.preferencesManager.getShowGuideAlways()

    // 首次使用 或 设置了常驻显示 → 自动展示面板
    if (!hasSeenGuide || this.showGuideAlways) {
    this.showGuide = true

    // 首次查看后标记为"已读",下次不再自动弹出
    if (!hasSeenGuide) {
    await this.preferencesManager.markGuideAsSeen()
    }
    }
    }

    设计要点:

    • 使用双条件判断:首次用户必看;老用户可选择常驻
    • markGuideAsSeen() 只在首次触发一次,之后由 showGuideAlways 接管

    二、内嵌式使用说明面板

    当 showGuide === true 时,在网格内容上方渲染一个卡片:

    // GridTimeline() Builder 中
    if (this.showGuide) {
    Column() {
    // 标题栏:标题 + 关闭按钮
    Row() {
    Text('使用说明')
    .fontSize(this.fs(16))
    .fontWeight(FontWeight.Bold)
    .fontColor($r('app.color.text_primary'))

    Blank()

    Button() { Text('×') }
    .backgroundColor(Color.Transparent)
    .onClick(async () => {
    this.showGuide = false
    // 关闭时若开启了常驻,则一并取消
    if (this.showGuideAlways) {
    this.showGuideAlways = false
    await this.preferencesManager.setShowGuideAlways(false)
    }
    })
    }
    .width('100%')
    .margin({ bottom: 8 })

    // 引导条目列表
    Column() {
    Text('• 点击空白格子:快速记录单个时间段')
    Text('• 长按并拖动:选择多个连续时间段')
    Text('• 点击已记录格子:编辑时间块')
    Text('• 左上角白点:标识时间块的起始位置')
    Text('• 金色边框:高质量时间(专注度≥4 且 价值感≥4)')

    Text('提示:可通过右上角 ? 按钮随时查看帮助')
    .fontStyle(FontStyle.Italic)
    }
    .alignItems(HorizontalAlign.Start)
    }
    .width('100%')
    .padding(16)
    .backgroundColor($r('app.color.card_background'))
    .borderRadius(8)
    .margin({ left: 8, right: 8, bottom: 12 })
    }

    布局要点:

    要素实现方式
    标题与关闭按钮同行 Row + Blank() 占据中间空间
    关闭按钮样式 背景透明、无 padding、仅显示 × 符号
    条目左对齐 外层 Column 设置 alignItems(HorizontalAlign.Start)
    底部提示区分级 斜体 + 灰色 + 较小字号

    关闭逻辑的细节:点击 × 时,不仅设 showGuide = false,还检查并同步取消常驻状态,保证 UI 和持久化数据一致。

    使用帮助


    三、浮动帮助按钮

    当内嵌面板隐藏时(!this.showGuide),在页面右上角显示一个圆形悬浮按钮:

    // build() 方法中的 Stack 布局内
    if (!this.showGuide) {
    Button() {
    Text('?')
    .fontSize(this.fs(20))
    .fontWeight(FontWeight.Bold)
    .fontColor(Color.White)
    }
    .width(48)
    .height(48)
    .borderRadius(24) // 正圆形
    .backgroundColor($r('app.color.primary_color'))
    .position({ x: '100%', y: 70 }) // 锚定右侧,y=70 是日期导航栏高度
    .translate({ x: 68, y: 20 }) // 向左偏移68,向下偏移20
    .shadow({
    radius: 12,
    color: $r('app.color.primary_shadow'),
    offsetX: 0,
    offsetY: 4
    })
    .onClick(() => {
    this.showGuideDialog()
    })
    }

    定位原理:

    • 整个页面使用 Stack 布局,浮动按钮作为叠加层放置
    • position({ x: '100%', y: 70 }) 将按钮锚定到容器右边缘,垂直位置在日期导航栏下方
    • translate({ x: -68, y: 20 }) 微调最终位置:距离右边距 20px,距离导航栏底部 20px(48px按钮宽度 + 20px边距 = 68px)
    • shadow 属性赋予按钮浮起感

    互斥显示:if (!this.showGuide) 保证面板和按钮不会同时出现。

    使用帮助2


    四、AlertDialog 帮助弹窗

    点击 ? 按钮后调用 showGuideDialog() 弹出系统对话框:

    private showGuideDialog(): void {
    AlertDialog.show({
    title: '使用说明',
    message: '• 点击空白格子:快速记录单个时间段\\n\\n' +
    '• 长按并拖动:先长按某个格子,再滑动选择多个连续时间段\\n\\n' +
    '• 点击已记录格子:编辑时间块\\n\\n' +
    '• 左上角白点:标识每个时间块的起始位置\\n\\n' +
    '• 金色边框:高质量时间(专注度≥4 且 价值感≥4)\\n\\n' +
    '• 左侧时间标签:显示每行的开始时间\\n\\n' +
    '• 格子颜色:整点格子较深,半点格子较浅',
    primaryButton: {
    value: this.showGuideAlways ? '关闭常驻显示' : '开启常驻显示',
    action: async () => {
    this.showGuideAlways = !this.showGuideAlways
    await this.preferencesManager.setShowGuideAlways(this.showGuideAlways)
    this.showGuide = this.showGuideAlways // 开启时常驻显示面板
    }
    },
    secondaryButton: {
    value: '知道了',
    action: () => {} // 仅关闭对话框
    },
    alignment: DialogAlignment.Center
    })
    }

    关键设计:

  • 动态按钮文案:主按钮文字根据当前状态切换——“开启常驻显示” ↔ “关闭常驻显示”
  • 双操作合一:点击主按钮同时完成:切换状态 → 持久化 → 控制 showGuide(开启时同步显示面板)
  • \\n\\n 分段:在 message 中使用双换行实现段落间距
  • 使用帮助3


    五、偏好设置持久化

    PreferencesManager 提供四个 API 管理使用说明状态:

    // PreferencesManager.ets 中相关方法

    private static readonly KEY_HAS_SEEN_GUIDE: string = 'has_seen_guide'
    private static readonly KEY_SHOW_GUIDE_ALWAYS: string = 'show_guide_always'

    // 检查是否首次查看
    async hasSeenGuide(): Promise<boolean> {
    return await this.prefs.get(KEY_HAS_SEEN_GUIDE, false) as boolean
    }

    // 标记为已查看(只执行一次)
    async markGuideAsSeen(): Promise<void> {
    await this.prefs.put(KEY_HAS_SEEN_GUIDE, true)
    await this.prefs.flush()
    }

    // 获取常驻显示设置
    async getShowGuideAlways(): Promise<boolean> {
    return await this.prefs.get(KEY_SHOW_GUIDE_ALWAYS, false) as boolean
    }

    // 切换常驻显示
    async setShowGuideAlways(show: boolean): Promise<void> {
    await this.pfs.put(KEY_SHOW_GUIDE_ALWAYS, show)
    await this.prefs.flush()
    }

    首次启动时在 setDefaultPreferences() 中写入默认值:

    await this.prefs.put(KEY_HAS_SEEN_GUIDE, false) // 默认未查看
    await this.prefs.put(KEY_SHOW_GUIDE_ALWAYS, false) // 默认非常驻

    底层使用 HarmonyOS 的 @ohos.data.preferences 轻量级 KV 存储,flush() 保证立即写入磁盘。

    赞(0)
    未经允许不得转载:171主机测评 » 【HarmonyOS 6】使用说明功能:浮动按钮、弹窗与偏好设置
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址