ArkUI 深浅色模式:局部预览,不冒充全局切换
【摘要】 深浅色适配不是把白底改成黑底。页面里的文字、边框、按钮和状态反馈都要重新检查对比度和语义。 本篇边界 这篇只做页面局部预览,不调用全局 setColorMode,也不改应用级主题策略。真实项目里,全局深浅色切换应由产品策略、系统设置和应用配置一起决定。 WithTheme 只改变主题资源的解析方式;硬编码十六进制颜色不
ArkUI 深浅色模式:局部预览,不冒充全局切换
深浅色适配不是把白底改成黑底。页面里的文字、边框、按钮和状态反馈都要重新检查对比度和语义。
本篇边界
这篇只做页面局部预览,不调用全局 setColorMode,也不改应用级主题策略。真实项目里,全局深浅色切换应由产品策略、系统设置和应用配置一起决定。
WithTheme 只改变主题资源的解析方式;硬编码十六进制颜色不会跟着系统深浅色变化。预览卡片读取 resources/base/element/color.json 和 resources/dark/element/color.json 中的同名 app.color 资源。
交互预期
- 点击“跟随系统 / 固定浅色 / 固定深色”,页面中间的预览区域会切换显示。
- “跟随系统”会按设备当前深浅色解析
color.json资源;如果设备当前就是浅色,它看起来会接近固定浅色。 - 下方状态文本会说明当前只是局部预览,没有修改应用全局模式。
Builder 刷新规则
本页已完成 @Builder 参数刷新检阅。模式按钮不再使用 modeButton(item, index) 多参数 Builder,改为 modeButton(index),在 Builder 内部读取 this.modes[index] 和 this.currentIndex。
完整示例代码
class ProductColorModeItem {
label: string
desc: string
mode: ThemeColorMode
constructor(label: string, desc: string, mode: ThemeColorMode) {
this.label = label
this.desc = desc
this.mode = mode
}
}
@Entry
@Component
struct ArkUIColorModeDemo {
@State currentIndex: number = 0
@State feedback: string = '当前只演示页面局部深浅色,不修改应用全局模式。'
private modes: ProductColorModeItem[] = [
new ProductColorModeItem('跟随系统', '卡片读取 color.json,随设备当前深浅色变化。', ThemeColorMode.SYSTEM),
new ProductColorModeItem('固定浅色', '同一组 app.color 资源被固定解析为浅色。', ThemeColorMode.LIGHT),
new ProductColorModeItem('固定深色', '同一组 app.color 资源被固定解析为深色。', ThemeColorMode.DARK)
]
private currentMode(): ProductColorModeItem {
return this.modes[this.currentIndex]
}
@Builder
previewSectionTitle() {
Column({ space: 6 }) {
Text('局部预览')
.fontSize(19)
.fontWeight(FontWeight.Bold)
.fontColor($r('app.color.color_mode_text_primary'))
Text('WithTheme 需要配合 color.json 资源使用,固定十六进制颜色不会随模式变化。')
.fontSize(13)
.fontColor($r('app.color.color_mode_text_secondary'))
.lineHeight(20)
}
.width('100%')
.alignItems(HorizontalAlign.Start)
}
@Builder
validationSectionTitle() {
Column({ space: 6 }) {
Text('验收重点')
.fontSize(19)
.fontWeight(FontWeight.Bold)
.fontColor($r('app.color.color_mode_text_primary'))
Text('深浅色不是只反转背景,还要检查文字、边框、按钮和状态反馈。')
.fontSize(13)
.fontColor($r('app.color.color_mode_text_secondary'))
.lineHeight(20)
}
.width('100%')
.alignItems(HorizontalAlign.Start)
}
@Builder
modeButton(index: number) {
Button(this.modes[index].label)
.height(42)
.layoutWeight(1)
.fontSize(14)
.fontColor(this.currentIndex === index ? '#FFFFFF' : '#334155')
.backgroundColor(this.currentIndex === index ? '#2563EB' : '#E5E7EB')
.onClick(() => {
const item = this.modes[index]
this.currentIndex = index
if (item.mode === ThemeColorMode.SYSTEM) {
this.feedback = '已切换预览:跟随系统。卡片读取 color.json,会按设备当前深浅色解析。'
} else {
this.feedback = `已切换预览:${item.label}。这只是局部主题演示,没有调用全局 setColorMode。`
}
})
}
@Builder
previewPanel() {
WithTheme({ colorMode: this.currentMode().mode }) {
Column({ space: 14 }) {
Text(this.currentMode().label)
.fontSize(22)
.fontWeight(FontWeight.Bold)
.fontColor($r('app.color.color_mode_text_primary'))
Text(this.currentMode().desc)
.fontSize(14)
.fontColor($r('app.color.color_mode_text_secondary'))
.lineHeight(22)
Row({ space: 10 }) {
Text('主按钮')
.fontSize(14)
.fontColor($r('app.color.color_mode_button_text'))
.padding({ left: 12, right: 12, top: 8, bottom: 8 })
.backgroundColor($r('app.color.color_mode_button_background'))
.borderRadius(8)
Text('次要信息')
.fontSize(14)
.fontColor($r('app.color.color_mode_text_primary'))
.padding({ left: 12, right: 12, top: 8, bottom: 8 })
.backgroundColor($r('app.color.color_mode_chip_background'))
.border({ width: 1, color: $r('app.color.color_mode_border') })
.borderRadius(8)
}
.width('100%')
}
.width('100%')
.padding(18)
.borderRadius(16)
.backgroundColor($r('app.color.color_mode_panel_background'))
.border({ width: 1, color: $r('app.color.color_mode_border') })
.alignItems(HorizontalAlign.Start)
}
}
build() {
Scroll() {
Column({ space: 18 }) {
Text('ArkUI 深浅色模式')
.fontSize(26)
.fontWeight(FontWeight.Bold)
.fontColor($r('app.color.color_mode_text_primary'))
.width('100%')
Text('先把应用深浅色适配的边界讲清楚:页面可以做局部预览,真正修改全局模式要放到应用级策略里。')
.fontSize(14)
.fontColor($r('app.color.color_mode_text_secondary'))
.lineHeight(22)
.width('100%')
this.previewSectionTitle()
Row({ space: 8 }) {
this.modeButton(0)
this.modeButton(1)
this.modeButton(2)
}
.width('100%')
this.previewPanel()
Text(this.feedback)
.width('100%')
.fontSize(14)
.fontColor($r('app.color.color_mode_text_primary'))
.lineHeight(22)
.padding(12)
.backgroundColor($r('app.color.color_mode_chip_background'))
.borderRadius(10)
this.validationSectionTitle()
}
.width('100%')
.padding(20)
.alignItems(HorizontalAlign.Start)
}
.width('100%')
.height('100%')
.backgroundColor($r('app.color.color_mode_page_background'))
}
}
【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)