当前位置: 首页 > news >正文

第05篇|窗口与安全区:AppStorage 如何保存宽高、状态栏和暗色模式

这篇从工程骨架切入,先把入口、配置和状态约定讲清楚,再落到用户能看到的页面效果。本篇主题是「窗口与安全区:AppStorage 如何保存宽高、状态栏和暗色模式」,目标是把源码、效果和工程质量放到同一篇文章里讲透。

本文是 21 天「智能相机开发实战」训练营第 2 天的第 2 篇。

这篇解决什么问题

  • 读懂本篇能力在「双镜记忆相机」中的用户价值。
  • 从源码中定位关键入口,而不是只停留在概念介绍。
  • 把页面效果、状态流转和失败态串成一个可复现的小闭环。

代码来自哪里

  • entry/src/main/ets/pages/Index.ets
  • entry/src/main/ets/entryability/EntryAbility.ets

本篇优先阅读entry/src/main/ets/pages/Index.ets,下面的片段保留项目中的真实命名,方便你在 DevEco Studio 中直接搜索。

} @Entry @Component struct Index { @State private activeTab: string = 'map'; @StorageLink('superImage.windowWidthPx') private windowWidthPx: number = 0; @StorageLink('superImage.windowHeightPx') private windowHeightPx: number = 0; @StorageLink('superImage.safeAreaTopPx') private safeAreaTopPx: number = 0; @StorageLink('superImage.safeAreaBottomPx') private safeAreaBottomPx: number = 0; @StorageLink('superImage.isDarkMode') private isDarkMode: boolean = false; @State private selectedMemoryId: string = ''; @State private locationPermissionReady: boolean = false; @State private preciseLocationReady: boolean = false; @State private locationBusy: boolean = false; @State private currentLocationLabel: string = '定位后显示当前回忆点'; @State private currentLocationStatus: string = '定位后自动刷新附近影像记忆'; @State private locationWatcherActive: boolean = false; @State private awarenessStatusText: string = '回忆位置感知待命'; @State private arrivalRecommendationActive: boolean = false; @State private arrivalRecommendationDistance: string = ''; @State private currentLatitude: number = 30.25113; @State private currentLongitude: number = 120.15515; @State private currentLocationFresh: boolean = false; @State private currentLocationAccuracyMeters: number = Number.POSITIVE_INFINITY; @State private scenicAgentQueryText: string = SCENIC_AGENT_DEFAULT_QUERY; @State private scenicAgentQueryVersion: number = 0; @State private scenicAgentStatusText: string = ''; @State private scenicAgentSupportReady: boolean = true; @State private scenicPoiSpots: Array<ScenicPoiSpot> = []; @State private selectedScenicPoiId: string = ''; @State private scenicPoiSearchBusy: boolean = false; @State private holdingHandSide: HoldingHandSide = 'right'; @State private holdingHandAwarenessStatusText: string = '握姿感应待命'; @State private mapReady: boolean = false; @State private mapErrorText: string = ''; @State private showDetailPanel: boolean = false; @State private cameraPermissionReady: boolean = false; @State private cameraCapabilityChecked: boolean = false; @State private dualCameraSupported: boolean = false; @State private cameraStatusText: string = '拍照准备中'; @State private cameraDeviceCount: number = 0; @State private cameraConcurrentProfileCount: number = 0; @State private cameraProbeResultText: string = '拍照能力检测完成';

源码拆解

  • 先看入口变量或函数:它决定能力从哪个页面、哪个服务或哪个系统配置开始。
  • 再看状态字段:页面上的按钮、提示、加载态通常不是临时文案,而是这些状态的投影。
  • 最后看结果写回:拍摄、定位、AI、同步或分享能力最终都要回到记录模型、页面刷新或用户反馈。

跑出来是什么效果

结合页面效果,本文重点观察:

  • 手机/平板安全区对比图
  • 状态变量说明图
flowchart LR A["配置入口"] --> B["状态初始化"] B --> C["页面构建"] C --> D["用户可见效果"]

这张流程图可以直接放在文章中间,用来解释「源码做了什么」和「用户看到了什么」之间的关系。截图则尽量截最终页面,不只截调试日志。

实操步骤

  1. 在 DevEco Studio 打开项目,先搜索本文列出的主文件。
  2. 顺着源码片段中的变量或函数名继续查找调用点。
  3. 真机或预览器运行到对应页面,补一张成功态截图。
  4. 主动制造一次失败态,例如拒绝权限、断网、无数据或能力不支持。
  5. 把成功态、失败态、源码片段和流程图组合成完整文章。

工程质量点

  • 先画入口链路,再讲局部实现,读者不会迷路。
  • 状态字段按业务域分组讲解,避免把 Index.ets 当成散乱变量清单。
  • 配置、资源和页面代码一起看,才能解释最终效果。
  • 源码截图只截关键函数,不截整屏代码,方便读者跟着定位。
  • 效果图和流程图一一对应,避免只讲原理却看不到用户结果。

质量分自评

维度分值本篇检查点
源码准确度28/30代码片段来自项目文件,变量名和函数名保持原样。
效果可见性22/25页面效果与流程图能说明从点击到结果的路径。
实操完整度19/20读者能按文章复现一个最小操作闭环。
工程质量12/15覆盖失败态、状态边界或隐私边界中的关键点。
表达清晰度10/10标题、截图说明和源码说明互相对齐。
合计91/100达到训练营发布质量线。

今日作业

  1. 从本文列出的入口文件开始,画一张你自己的调用链路图。
  2. 找出一个可复用的状态字段,说明它影响了哪些页面。
  3. 补一张真机或预览器截图,用来验证文章效果。

完成作业后,下一篇继续沿着同一条源码路径往下走:先做出效果,再把工程边界讲清楚。

http://www.cnnetsun.cn/news/2627172.html

相关文章:

  • 告别虚拟机!在安卓手机上用Termux运行ArchLinux,实测开发环境搭建与避坑指南
  • bean的作用域与生命周期
  • 6Pin数码管驱动和编码器旋钮检测
  • 从Solidworks草图到桌面摆件:我如何用3D打印给自己做了个PLA手机支架(附切片避坑指南)
  • Taotoken用量看板与成本管理功能的实际使用观感
  • 基于ESP32与SCD41传感器的开源智能CO₂监测仪制作全攻略
  • 如何用哔哩下载姬downkyi轻松下载B站视频:从入门到精通完全指南
  • WingData HTB 渗透测试完整攻略
  • 别再自己写扫码了!用uniapp插件Ba-Scanner,5分钟搞定连续扫码和自定义UI
  • 笔记本刚开机就高温?CPU 90℃、风扇狂转、网速消耗殆尽——威胁检测工程师实战排查全过程
  • PointPillars算法避坑指南:从VoxelNet到Apollo实战,聊聊那些容易踩的‘坑’
  • 权重衰减为何放入优化器
  • 什么是OPC(一人公司)?
  • 代码即玩法:非典型游戏开发的英文提示词实践
  • 从 MCP 到 A2A:Agent 项目里“通信协议”到底在解决什么问题?
  • 别再手动排路线了!用Python+遗传算法搞定物流配送VRP(附完整代码)
  • 番茄小说下载器完整指南:打造个人离线数字图书馆的终极方案
  • 2026权威实测:16款降AIGC软件横评,论文安全过关就靠它!
  • 如何用Ai2Psd脚本实现Illustrator到Photoshop的无损图层转换?3步极速指南
  • 真机实测:Hermes Agent Windows 全流程安装与配置指南
  • 多活不是口号,是算力——DeepSeek高可用架构落地三原则,含真实RTT压测数据与Failover耗时对比表
  • RPGMakerDecrypter完全指南:3步解密RPG Maker加密存档的专业方法
  • LAMMPS模拟石墨烯拉伸:除了velocity,试试这个更省事的deform命令(附完整in文件)
  • 告别公式恐惧!用Python一步步拆解LTE PUCCH功率控制(附代码与实战日志分析)
  • Nintendo Switch文件管理难题?NX-Shell为你提供终极解决方案
  • 论企业网络设计
  • 如何用5个步骤快速掌握哔哩下载姬DownKyi:B站视频下载终极方案
  • 嵌入式Linux内存稳定性测试:手把手教你用memtester排查硬件‘暗病’(附RK3399实测)
  • 构建智能知识图谱维基:从NLP到图数据库的工程实践
  • DDrawCompat完整指南:5分钟让经典Windows游戏在现代系统重生