项目7-七彩天气app任务7.4.2“关于”弹窗

上述弹窗,可以使用ArkUI中的promptAction,用于创建并显示文本提示框、对话框和操作菜单。

此任务在IndexPersonalPage.ets中增加相关"关于"弹窗的代码之后的整体代码如下,

java 复制代码
// IndexPersonalPage.ets
import { i18n } from '@kit.LocalizationKit'
import { STATUS_BAR_HEIGHT } from '../../entryability/EntryAbility';
import bundleManager from '@ohos.bundle.bundleManager'
import { util } from '@kit.ArkTS'
import { BaseUtils } from '../../utils/BaseUtils'
import promptAction from '@ohos.promptAction'

@Preview
@Component
export struct IndexPersonalPage {
  private appVersionName: string = ''

  // 使用@Builder 显示个人数据
  @Builder
  datashow(name: Resource, value: number) {
    Column() {
      Text(value.toString()).fontColor($r('app.color.gray3')).fontSize(20)
      Blank().height(10)
      Text(name).fontColor($r('app.color.gray7')).fontSize(16)
    }

  }

  // 在aboutToApper中调用获取方法
  aboutToAppear(): void {
    this.getAppInfo()
  }

  // 异步获取版本信息
  async getAppInfo() {
    let result = await bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION)
    this.appVersionName = result.versionName
    // 也可以直接使用
    // this.appVersionName = BuildProfile.VERSION_NAME
  }

  // 功能条
  @Builder
  functionalBar(icon: Resource, title: Resource, click: (event: ClickEvent) => void) {
    Column() {
      Row() {
        Image(icon).width(30)
        Text(title).margin({ left: 20 }).fontSize(16)
        Blank()
        SymbolGlyph($r('sys.symbol.chevron_right')).fontSize(26)
      }.width('100%').height(60)
      .padding({ left: 20, right: 20 })

      Divider().width('100%').margin({ left: 20 })
    }.backgroundColor(Color.White)
    .onClick(click)
    .stateStyles({
      normal: {
        .backgroundColor(Color.White)
      },
      clicked: {
        .backgroundColor($r('app.color.grayE'))
      }
    })
  }

  build() {
    Scroll() {
      Column() {
        Column() {
          // 头像
          Image($r('app.media.avatar_male'))
            .width(70).borderRadius(35)
            .margin({ top: STATUS_BAR_HEIGHT })

          // 名称
          Text('华为用户').margin({ top: 15 }).fontSize(20).fontWeight(500)
          // 3个数据
          Row() {
            this.datashow($r('app.string.personal_follow'), 0)
            this.datashow($r('app.string.personal_fans'), 0)
            this.datashow($r('app.string.personal_praise'), 0)
          }
          .margin({ top: 15 })
          .width('100%')
          .justifyContent(FlexAlign.SpaceAround)
        }.backgroundImage($r('app.media.bg_personal_head'))
        .backgroundImageSize(ImageSize.FILL)
        .width('100%').height(230)

        this.functionalBar($r("app.media.ic_func_language"), $r('app.string.personal_language'), () => {
          console.log('语言', i18n.System.getAppPreferredLanguage())
          // 简体中文和美国英文切换
          if (i18n.System.getAppPreferredLanguage() != 'zh-Hans') {
            i18n.System.setAppPreferredLanguage('zh-Hans')
          } else {
            i18n.System.setAppPreferredLanguage('en-US')
          }
        })

        this.functionalBar($r('app.media.ic_func_feedback'), $r('app.string.personal_feedback'), () => {

        })
        this.functionalBar($r('app.media.ic_func_about'), $r('app.string.personal_about'), async () => {
          const result = await promptAction.showDialog({
            title: $r('app.string.about_title'),
            message: util.format(BaseUtils.getStr($r('app.string.about_content')), this.appVersionName),
            buttons: [
              { text: $r('app.string.btn_sure'), color: $r('app.color.main_color'), primary: false }
            ]
          })
          console.log('点击的按钮索引为:', result.index)
        })
      }
    }
  }
}

// 展示个人数据组件
@Component
struct DataShow {
  title?: Resource
  // 父向子单向同步
  @Prop content: number

  build() {
    Column() {
      Text(this.content + '')
        .fontColor($r('app.color.gray3')).fontSize(20)
        .onClick(() => {
          this.content++
        })
      Blank().height(10)
      Text(this.title ?? '')
        .fontColor($r('app.color.gray7')).fontSize(16)
    }
  }
}
类别 修改前 修改后 差异说明
功能新增 无"关于"弹窗 "关于"功能点击后显示含应用版本号的对话框 新增动态获取并展示 App 版本信息
API 调用 未使用系统 API 获取版本 引入 @ohos.bundle.bundleManager 异步获取 versionName 使用官方 Bundle 管理接口读取应用元数据
生命周期方法 新增 aboutToAppear() 在页面即将出现时触发初始化逻辑
UI 交互 "关于"按钮无响应 "关于"按钮调用 promptAction.showDialog 显示模态对话框 增强用户反馈,提升体验
字符串格式化 使用 util.format() + 自定义工具类 BaseUtils.getStr() 实现多语言+动态参数填充
依赖导入 仅基础模块 新增 bundleManager, util, BaseUtils, promptAction 扩展功能所需模块

💡 注意:虽然代码末尾仍保留了未使用的 DataShow 组件,但主页面中并未实际使用它(仍用 @Builder datashow),此为冗余代码,建议后续清理。


🔍 二、关键修改点详解

1. 新增 aboutToAppear() 生命周期钩子

复制代码
aboutToAppear(): void {
  this.getAppInfo()
}
  • 作用:在组件即将进入视图前执行初始化操作(如加载数据)。
  • 知识点
    • aboutToAppear() 是 ArkTS 中 @Component 的标准生命周期回调,等价于 Android 的 onResume() 或 Web 的 connectedCallback
    • 适合用于异步数据预加载 ,避免在 build() 中直接调用 async(会破坏声明式 UI 的纯函数特性)。

2. 通过 bundleManager 获取应用版本号

复制代码
async getAppInfo() {
  let result = await bundleManager.getBundleInfoForSelf(
    bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION
  )
  this.appVersionName = result.versionName
}
  • 作用 :从系统包管理器中读取当前应用的 versionName(如 "1.2.0")。
  • 知识点
    • @ohos.bundle.bundleManager 是鸿蒙系统提供的应用信息查询接口
    • getBundleInfoForSelf() 获取自身应用的 Bundle 信息。
    • 需要申请权限?✅ 不需要------读取自身信息属于安全白名单操作。
    • 替代方案:也可使用编译时常量 BuildProfile.VERSION_NAME(但需确保 build-profile 正确配置)。

3. "关于"按钮绑定异步弹窗

复制代码
this.functionalBar(..., async () => {
  const result = await promptAction.showDialog({ ... })
})
  • 作用:点击"关于"时弹出包含版本号的提示框。
  • 知识点
    • @ohos.promptAction 提供系统级对话框(showDialog),阻塞式交互,返回用户点击的按钮索引。
    • 使用 async/await 处理 Promise 返回值,符合 ArkTS 异步编程规范。
    • 对话框内容使用 util.format(str, args...) 实现占位符替换(类似 C 的 printf 或 JS 的模板字符串)。
  1. 字符串本地化 + 动态参数注入

    message: util.format(BaseUtils.getStr($r('app.string.about_content')), this.appVersionName)

  • 作用 :将多语言字符串中的 {0} 占位符替换为实际版本号。

  • 假设 about_content 定义为

    复制代码
    "about_content": "当前版本:{0}\n© 2025 华为技术有限公司"
  • 知识点

    • $r('app.string.xxx'):引用 resources/base/element/string.json 中的多语言资源。
    • BaseUtils.getStr():可能是封装了 $r().toString() 的工具方法(因 $r() 返回 Resource 对象,需转字符串)。
    • util.format():ArkTS 内置的字符串格式化函数,支持 {0}, {1} 等索引占位。
相关推荐
奇舞精选2 小时前
GELab-Zero 技术解析:当豆包联手中兴,开源界如何守住端侧 AI 的“最后防线”?
前端·aigc
奇舞精选2 小时前
Vercel AI SDK:构建现代 Web AI 应用指南
前端·aigc
小鸡吃米…2 小时前
Python PyQt6教程三-菜单与工具栏
开发语言·python
aini_lovee2 小时前
寻找 MAC 协议的 MATLAB 仿真
开发语言·macos·matlab
Jelena157795857923 小时前
Java爬虫淘宝拍立淘item_search_img拍接口示例代码
开发语言·python
神仙别闹3 小时前
基于C语言实现B树存储的图书管理系统
c语言·前端·b树
郝学胜-神的一滴3 小时前
Python数据模型:深入解析及其对Python生态的影响
开发语言·网络·python·程序人生·性能优化
玄魂3 小时前
如何查看、生成 github 开源项目star 图表
前端·开源·echarts
一水鉴天3 小时前
整体设计 定稿 之26 重构和改造现有程序结构 之2 (codebuddy)
开发语言·人工智能·重构·架构