鸿蒙原生应用 ArkUI 实战:虚线人脸框 + 双按钮 —— 证件照拍摄页的取景引导架构
·
鸿蒙原生应用 ArkUI 实战:虚线人脸框 + 双按钮 —— 证件照拍摄页的取景引导架构
App 51「个人证件照制作」拍摄页(Func1Tab),主题色
#2D3436深灰黑(charcoal),4 个 Tab 分别为首页(🪪)、拍摄(📷)、编辑(✂️)、我的(👤)。本篇基于51-id-photo/entry/src/main/ets/pages/Func1Tab.ets(共 78 行)逐段拆解,附 4 张实机截图。

一、整体结构:四区"Header + 相机 + 动作 + 贴士"布局
拍摄页是"品牌头部 + 相机预览 + 拍摄动作 + 拍摄指导"的四区布局——3 个 @Builder 块:
build() {
Column() {
this.Header()
Scroll() {
Column({ space: 16 }) {
this.CameraCard()
this.ActionRow()
this.TipCard()
}
.width('100%')
.padding({ left: D.pad, right: D.pad, top: 16, bottom: D.pad + this.safeBottom + 20 })
}
.layoutWeight(1).scrollBar(BarState.Off).align(Alignment.Top)
}
.width('100%').height('100%').backgroundColor(C.bg)
}
4 块结构:Header(单行标题)→ CameraCard(相机预览+虚线人脸框)→ ActionRow(拍摄/上传双按钮)→ TipCard(4 条拍摄规范)。拍摄页是"照片的来源端"——相机预览引导"怎么拍"、双按钮提供"拍摄 or 上传"两种来源、贴士卡给出拍摄规范。
二、Header:单行标题
Header() {
Row() { Text('拍摄照片').fontSize(20).fontWeight(FontWeight.Bold).fontColor(C.text) }
.width('100%').height(this.safeTop + 56).padding({ top: this.safeTop, left: D.pad, right: D.pad })
.backgroundColor(C.card).alignItems(VerticalAlign.Bottom)
}
20 号加粗、safeTop + 56 高度、白底底部对齐——系列二级页统一范式。"拍摄照片"与首页"证件照制作"(选规格)、编辑页"编辑照片"(修照片)形成"选 → 拍 → 编"流水线。
三、CameraCard:相机预览卡(虚线人脸框)
CameraCard() {
Stack({ alignContent: Alignment.Center }) {
Column().width('100%').height(300).backgroundColor('#2D3436').borderRadius(D.rLg)
Column({ space: 12 }) {
Text('👤').fontSize(80).opacity(0.5)
Text('请将面部置于框内').fontSize(13).fontColor('#FFFFFF').opacity(0.8)
}
Column()
.width(140).height(180)
.border({ width: 2, color: '#FFFFFF', style: BorderStyle.Dashed }).borderRadius(8)
}
.width('100%')
}
逐点拆解:
- Stack 三层叠加:底层深灰底(
#2D3436300 高圆角 20)→ 中层人像引导(👤 80 号 50% 透明 + "请将面部置于框内"白字 80%)→ 顶层虚线框(140×180 白色虚线)——相机取景的视觉层次(背景/内容/取景框)。 - 虚线人脸框:
BorderStyle.Dashed+ 白 2 宽 + 圆角 8——140×180 对应证件照的"头身比"(头占画面约 70%),虚线"待填充"语义(把脸放入虚线框),与系列"虚线 = 待填充"(App 44 上传条、App 49 添加)语义一致。 - 半透明人像占位:
opacity(0.5)——👤 80 号半透明是"示意图"(不是真照片,是"这样拍"的示例),与虚线框共同构成拍摄示意。 - 深灰底的双重语义:
#2D3436既模拟相机取景画面(证件照深色背景标准)又是主题色——拍摄页的深灰与全 App 主题统一。
四、ActionRow:拍摄/相册双按钮
ActionRow() {
Row({ space: 12 }) {
Button('📷 拍摄').fontSize(15).fontColor('#FFFFFF').backgroundColor(C.primary)
.layoutWeight(1).height(48).borderRadius(D.rMd)
.onClick(() => { promptAction.showToast({ message: '拍摄照片' }); })
Button('🖼️ 相册上传').fontSize(15).fontColor(C.primary).backgroundColor(C.primarySoft)
.layoutWeight(1).height(48).borderRadius(D.rMd)
.onClick(() => { promptAction.showToast({ message: '从相册选择' }); })
}.width('100%')
}
逐点拆解:
- 双按钮等分:两个
layoutWeight(1)各占一半,48 高圆角 14——拍摄/上传两种照片来源。 - 主次视觉:📷 拍摄
C.primary深灰底白字(主动作)+ 🖼️ 相册上传C.primarySoft浅底深字(次动作)——视觉权重区分(拍摄优先)。 - 点击分支:拍摄 → "拍摄照片" Toast、上传 → "从相册选择" Toast——产品化后拍摄调
@ohos.multimedia.camera、上传调PhotoViewPicker。

五、TipCard:拍摄小贴士(规范清单)
private tips: string[] = ['正对镜头,表情自然', '光线充足,避免阴影', '不戴帽子和有色眼镜', '穿深色上衣效果更佳'];
TipCard() {
Column({ space: 12 }) {
Text('💡 拍摄小贴士').fontSize(14).fontWeight(FontWeight.Bold).fontColor(C.text).width('100%')
ForEach(this.tips, (t: string, idx: number) => {
Row({ space: 8 }) {
Text('✓').fontSize(13).fontColor(C.ok)
Text(t).fontSize(13).fontColor(C.textSub).layoutWeight(1)
}.width('100%')
}, (t: string) => t)
}
.width('100%').padding(16).backgroundColor(C.card).borderRadius(D.rLg).border({ width: 1, color: C.stroke })
}
逐点拆解:
- 4 条硬性规范:正对镜头/光线充足/不戴帽子有色眼镜/穿深色上衣——覆盖姿态/光线/遮挡/着装,是证件照合规的检查清单。
- ✓ 绿色勾选:
C.ok(#2BB673)绿色 + 13 号贴士文字——✓ 是"标准动作"的符号(每条都是"应该这样做"的规范)。 - "穿深色上衣"与主题呼应:贴士的"深色上衣"与主题色
#2D3436深灰呼应——证件照着装建议与视觉主题统一。 - ForEach key:
(t: string) => t——贴士文字天然唯一。

六、系列横向对比:拍摄/引导类页面的三种形态
| 引导页 | 代表 App | 引导方式 | 核心元素 | 虚线语义 |
|---|---|---|---|---|
| 拍摄引导 | App 51 拍摄页 | 虚线人脸框 + 贴士 | 140×180 取景框 | 人脸位置 |
| 上传引导 | App 44 相册页 | 虚线上传条 | 添加入口 | 待添加 |
| 制作引导 | App 43 明信片 | 实时预览 | 预览联动 | 无虚线 |
差异点:本页虚线框是"位置引导"(放哪里),最接近真实相机的取景框;App 44 虚线是"添加引导"(点这里添加);App 43 是"预览引导"(看效果)。三类引导语义分明。
七、开发者视角:调试与验证技巧
Column().width('100%').height(300).backgroundColor('#2D3436').borderRadius(D.rLg)
- 虚线框对齐:140×180 虚线框在 300 高深灰底上居中(
Stack alignContent Center)——验证虚线框与人像 👤 水平垂直居中重叠。 - 双按钮分支:两个独立
onClick——验证"拍摄照片"与"从相册选择"两路径正确触发;主次按钮视觉(深灰 vs 浅底)不混淆。 - 贴士渲染:4 条
ForEach——验证 ✓ 绿色与文字垂直对齐;新增贴士(数组加项)自动渲染。 - 深灰底对比度:
#2D3436+ 白虚线 + 白字——真机验证深底白字清晰;👤 80 号 50% 透明度在深灰上可辨但不抢戏。 - 产品化相机接入:Demo 静态取景——产品化后深灰底换
@ohos.multimedia.camera预览流,虚线框叠加在画面上(人脸识别可加"对齐提示"),虚线框骨架不变。

八、演进方向
| 方向 | 当前状态 | 产品化演进 |
|---|---|---|
| 相机预览 | 静态深灰底 + 👤 示意 | @ohos.multimedia.camera 实时预览流 |
| 人脸对齐 | 静态虚线框 | 人脸识别 + 框变绿提示对齐 |
| 拍摄按钮 | Toast"拍摄照片" | 调起相机拍摄 → 跳编辑页 |
| 上传按钮 | Toast"从相册选择" | 调 PhotoViewPicker 选照片 → 跳编辑页 |
| 贴士增强 | 静态 4 条文字 | 实时检测(光线不足/人脸偏移)动态提示 |
九、一句话总结
拍摄页以"相机预览卡 + 双按钮 + 贴士"完成了照片来源的引导。Stack 三层叠加(深灰底 + 半透明人像 + 140×180 白色虚线框)是取景引导的核心、layoutWeight(1) 双按钮主次分明、4 条 ✓ 拍摄规范是合格证件照的检查清单——78 行代码,一个"按规范拍好证件照"的拍摄页,也是相机引导类页面的标准参考。

更多推荐





所有评论(0)