在鸿蒙应用开发中,灵活的主题设置能力是实现个性化用户体验的关键技术,HarmonyOS NEXT提供了强大而灵活的主题设置功能,让开发者能够轻松实现应用级和页面级的主题定制。

在当今追求个性化的时代,用户希望应用能够根据自己的喜好呈现不同的视觉风格。鸿蒙NEXT(HarmonyOS NEXT)作为华为推出的分布式操作系统,提供了一套完整的主题设置解决方案,让开发者可以轻松实现应用级和页面级的主题定制能力。

1. 鸿蒙主题系统架构概述

鸿蒙操作系统的主题引擎基于声明式UI框架ArkUI构建,采用三层优先级策略

  1. 应用默认主题(优先级100)

  2. 用户自定义主题(优先级200)

  3. 系统全局主题(优先级300)

这种层级架构使得主题管理既灵活又有序,确保了在不同优先级下的主题属性能够正确覆盖和继承。

2. 应用级主题设置

应用级主题设置会在整个应用范围内生效,是统一应用视觉风格的最佳方式。

2.1 自定义品牌色

首先,我们需要定义自定义主题类,只需要复写需要修改的部分,未修改的内容会继承于系统默认值:

typescript

import { CustomColors, CustomTheme } from '@kit.ArkUI'export class AppColors implements CustomColors {// 自定义品牌色brand: ResourceColor = '#FF75D9';
}export class AppTheme implements CustomTheme {public colors: AppColors = new AppColors()
}export let gAppTheme: CustomTheme = new AppTheme()

2.2 设置应用级主题

在页面入口处统一设置应用级主题,需要在页面build之前执行ThemeControl:

typescript

import { Theme, ThemeControl } from '@kit.ArkUI'
import { gAppTheme } from './AppTheme'// 在页面build前执行ThemeControl
ThemeControl.setDefaultTheme(gAppTheme)@Entry
@Component
struct DisplayPage {@State menuItemColor: ResourceColor = $r('sys.color.background_primary')onWillApplyTheme(theme: Theme) {this.menuItemColor = theme.colors.backgroundPrimary;}build() {// 页面内容}
}

2.3 在Ability中设置主题

在Ability的onWindowStageCreate()方法中设置默认主题:

typescript

import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';export default class EntryAbility extends UIAbility {onWindowStageCreate(windowStage: window.WindowStage) {// 设置应用默认主题ThemeControl.setDefaultTheme(gAppTheme);// 其他初始化代码}
}

3. 页面级主题设置

页面级主题设置允许我们在单个页面内实现特殊的主题风格,满足特定页面的视觉需求。

3.1 局部深浅色模式设置

鸿蒙NEXT支持在单个页面内实现局部深浅色模式切换:

typescript

@Entry
@Component
struct ThemeExample {@State currentTheme: Theme = THEME_LIGHT;build() {Column() {// 深浅色模式切换按钮Button('切换深浅模式').onClick(() => {this.currentTheme = this.currentTheme === THEME_LIGHT ? THEME_DARK : THEME_LIGHT;ThemeControl.setCurrentTheme(this.currentTheme);})// 页面内容Text('局部深浅色模式示例').fontColor($r('sys.color.ohos_id_color_text_primary'))}.width('100%').height('100%').backgroundColor($r('sys.color.ohos_id_color_background'))}
}

3.2 动态主题切换

通过ThemeManager API实现动态主题切换,支持无闪烁过渡动画:

typescript

// 获取主题管理器实例
const themeManager = ThemeManager.getInstance();// 监听主题变化事件
themeManager.on('themeChange', (newTheme) => {console.info(`主题已切换至:${newTheme}`);
});// 切换至夜间模式
themeManager.changeTheme('dark').then(() => {console.info('主题切换完成');
}).catch((err) => {console.error(`切换失败:${err.code}`);
});

4. 主题继承与覆盖策略

鸿蒙支持多级主题继承体系,开发者可以创建基础主题并派生子主题。覆盖规则遵循:

  1. 子主题属性优先于父主题

  2. 数值型属性叠加计算

  3. 颜色属性完全覆盖

继承配置示例:

json

{"parent": "BaseTheme","attributes": {"colorAccent": "#3498DB","elevationMedium": "6vp"}
}

5. 主题资源管理

5.1 资源目录结构

鸿蒙采用模块化资源组织方式,支持按设备类型、屏幕密度、语言环境等20+维度进行智能匹配:

text

resources/
├─ base/
│ ├─ element/
│ ├─ media/
│ └─ profile/
├─ en_US/
├─ zh_CN/
└─ device/├─ phone/└─ tablet/

5.2 定义颜色资源

resources/base/element/colors.xml中定义颜色资源:

xml

<resources><color name="primary_color">#6200EE</color><color name="primary_light_color">#BB86FC</color><color name="primary_dark_color">#3700B3</color><color name="text_color">#FFFFFF</color>
</resources>

5.3 定义样式资源

resources/base/element/styles.xml中定义主题和样式:

xml

<resources><style name="AppTheme"><item name="colorPrimary">@color/primary_color</item><item name="colorPrimaryDark">@color/primary_dark_color</item><item name="colorText">@color/text_color</item></style><style name="CustomButton"><item name="background">@color/primary_color</item><item name="textColor">@color/text_color</item><item name="padding">16vp</item><item name="cornerRadius">8vp</item></style>
</resources>

6. 用户偏好存储与同步

6.1 保存主题偏好

使用首选项(Preferences)保存用户的主题选择:

typescript

const options: dataStorage.Options = {name: 'user_prefs',securityLevel: dataStorage.SecurityLevel.S1
};dataStorage.getPreferences(context, options).then(pref => {pref.put('theme', 'dark', (err) => {if (!err) console.info('主题偏好保存成功');});});

6.2 跨设备主题同步

通过分布式数据管理实现多设备主题同步:

typescript

// 创建同步回调
const syncCallback: dataSync.SyncCallback = {onComplete: (data) => {console.info('主题同步完成');},onConflict: (conflicts) => {return conflicts.server; // 采用服务端数据}
};// 发起数据同步
dataSync.sync({bundleName: 'com.example.app',sessionId: 'USER_SETTINGS'
}, syncCallback);

7. 实战案例:实现动态主题切换应用

下面通过一个完整示例演示如何实现动态主题切换功能。

7.1 定义主题资源

创建AppTheme.ts文件定义多个主题:

typescript

import { CustomColors, CustomTheme } from '@kit.ArkUI'// 浅色主题
class LightColors implements CustomColors {brand: ResourceColor = '#FF75D9';backgroundPrimary: ResourceColor = '#FFFFFF';textPrimary: ResourceColor = '#000000';
}class LightTheme implements CustomTheme {public colors: LightColors = new LightColors();
}// 深色主题
class DarkColors implements CustomColors {brand: ResourceColor = '#FF75D9';backgroundPrimary: ResourceColor = '#000000';textPrimary: ResourceColor = '#FFFFFF';
}class DarkTheme implements CustomTheme {public colors: DarkColors = new DarkColors();
}export let themes = {light: new LightTheme(),dark: new DarkTheme()
}

7.2 实现主题切换界面

typescript

@Entry
@Component
struct ThemeSwitcher {@State currentTheme: string = 'light';build() {Column() {// 主题切换按钮Row() {Button('浅色主题').onClick(() => this.changeTheme('light')).backgroundColor(this.currentTheme === 'light' ? '#FF75D9' : '#D3D3D3')Button('深色主题').onClick(() => this.changeTheme('dark')).backgroundColor(this.currentTheme === 'dark' ? '#FF75D9' : '#D3D3D3')}.padding(10).width('100%').justifyContent(FlexAlign.SpaceEvenly)// 页面内容Column() {Text('当前主题: ' + this.currentTheme).fontSize(20).fontColor($r('sys.color.ohos_id_color_text_primary'))Text('这是一段示例文本').fontSize(16).margin({ top: 20 }).fontColor($r('sys.color.ohos_id_color_text_primary'))}.width('100%').height('80%').backgroundColor($r('sys.color.ohos_id_color_background'))}.width('100%').height('100%')}private changeTheme(themeName: string) {this.currentTheme = themeName;ThemeControl.setDefaultTheme(themes[themeName]);}
}

8. 主题开发最佳实践

  1. 模块化样式:将样式按功能模块划分,避免过度集中。

  2. 命名规范:为样式、颜色和资源命名时,保持语义化和一致性。

  3. 重用与扩展:优先使用继承机制,减少重复定义。

  4. 适配多设备:使用Qualifier管理不同设备分辨率和模式的资源。

  5. 性能优化:避免在主题切换时进行不必要的UI重绘。

结语

鸿蒙NEXT的主题设置能力为开发者提供了强大的个性化定制工具,无论是应用级还是页面级的主题设置,都能轻松实现。通过合理的主题设计和资源管理,可以大幅提升应用的用户体验和视觉一致性。

随着鸿蒙生态的不断发展,主题定制功能将变得更加丰富和易用,为开发者和用户带来更多个性化体验的可能性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/95637.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/95637.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/95637.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

全球汽车氮化镓技术市场规模将于2031年增长至180.5亿美元,2025-2031年复合增长率达94.3%,由Infineon和Navitas驱动

全球汽车氮化镓技术市场规模将于2031年增长至180.5亿美元&#xff0c;2025-2031年复合增长率达94.3%&#xff0c;由Infineon和Navitas驱动汽车氮化镓技术正从一个有前景的细分市场加速进入主流电力电子领域。根据QYResearch&#xff08;恒州博智&#xff09;的《全球汽车GaN技术…

xftp断网后提示错误如何继续下载?

问题&#xff1a;xftp断网后提示错误如何继续下载&#xff1f;解决方法&#xff1a;断网后&#xff0c;先连接上网&#xff0c;然后继续双击右侧的那两个要传输的文件&#xff0c;然后会弹出一个覆盖还是继续下载&#xff08;如下图&#xff09;的选择框&#xff0c;选择继续下…

Day22_【机器学习—集成学习(4)—Boosting—GBDT算法】

提升树 &#xff08;Boosting Decision Tree &#xff09;每一个弱学习器通过拟合残差来构建强学习器梯度提升树 &#xff08;Gradient Boosting Decision Tree&#xff09;每一个弱学习器通过拟合负梯度来构建强学习器一、提升树残差数学公式为&#xff1a;残差真实值−预测值…

前缀和、子矩阵的和;差分、差分矩阵

一、前缀和数组要稍微注意前缀和数组从1开始#include <iostream>using namespace std;const int N 100010;int n, m; int a[N], s[N];int main() {scanf("%d%d", &n, &m);for (int i 1; i < n; i ) scanf("%d", &a[i]);for (int i…

启用BBR拥塞控制算法

目录 &#x1f4cb; 先决条件 &#x1f527; 启用步骤 &#x1f4dd; 额外检查与说明 ⚠️ 注意事项 BBR&#xff08;Bottleneck Bandwidth and Round-trip time&#xff09;是谷歌开发的一种TCP拥塞控制算法&#xff0c;它能有效提升网络传输速度和性能&#xff0c;尤其在…

Python:AI开发第一语言的全面剖析

文章目录引言1. Python的历史与AI开发的契合1.1 Python的诞生与设计哲学1.2 Python与AI发展的历史交汇2. 语言特性如何支持AI开发2.1 动态类型与交互式编程2.2 简洁优雅的语法2.3 高级数据结构的原生支持2.4 函数式编程特性2.5 强大的元编程能力3. 丰富的AI生态系统和库支持3.1…

Nikto 漏洞扫描工具使用指南

目录 ✨ 核心功能一览 &#x1f680; 基本使用方法 1. 扫描单个目标 2. 指定端口扫描 3. 扫描 HTTPS 目标 使用 -ssl 参数主要有两个核心原因 ⚙️ 高级使用技巧 1. 使用代理扫描 2. 保存扫描结果 3. 使用特定插件 4.交互命令 ✨ 核心功能一览 Nikto 是一款开源的 W…

FunASR的Java实现Paraformer实时语音识别 | 一款无需联网的本地实时字幕软件

0. 开发背景 我们在看直播时&#xff0c;没有视频字幕&#xff0c;可能看惯了视频字幕&#xff0c;来到直播中缺少字幕会感觉不习惯&#xff0c;特别是对于听力障碍的人群&#xff0c;只能依赖于字幕&#xff0c;那么这个软件可以解决直播&#xff0c;在线会议等场景中无字幕的…

从机器学习的角度实现 excel 中趋势线:揭秘梯度下降过程

1. 引言&#xff1a;Excel 的“一键魔法”背后藏着什么智慧&#xff1f;在 Excel 中&#xff0c;我们只需右键 → 添加趋势线&#xff0c;一条完美的直线就出现了。它快得像魔法&#xff0c;但魔法背后&#xff0c;是数学的严谨。今天&#xff0c;我们不关心 Excel 内部用了什么…

关于上拉电阻

上拉电阻的作用&#xff1a;辅助浮空状态输出高电平 其实就是确定这根线的电平&#xff0c;不能让他处于一种未知的状态。 其次也可以起到限制电流的作用&#xff0c;防止损坏原件 那么上拉电阻如何取值&#xff1f; 首先来看一下驱动能力。 因为线上是一定有寄生电容的&am…

PiscCode构建Mediapipe 手势识别“剪刀石头布”小游戏

在计算机视觉与人机交互领域&#xff0c;手势识别是一个非常有趣的应用场景。本文将带你用 Mediapipe 和 Python 实现一个基于摄像头的手势识别“剪刀石头布”小游戏&#xff0c;并展示实时手势与游戏结果。 1. 项目概述 该小游戏能够实现&#xff1a; 实时检测手势&#xff0…

【VoNR】VoNR 不等于 VoLTE on 5G

博主未授权任何人或组织机构转载博主任何原创文章&#xff0c;感谢各位对原创的支持&#xff01; 博主链接 本人就职于国际知名终端厂商&#xff0c;负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作&#xff0c;目前牵头6G技术研究。 博客内容主要围绕…

计算机网络:网络设备在OSI七层模型中的工作层次和传输协议

OSI七层模型&#xff08;物理层、数据链路层、网络层、传输层、会话层、表示层、应用层&#xff09;中&#xff0c;不同网络设备因功能不同&#xff0c;工作在不同层次。以下是典型网络设备的工作层次及核心功能&#xff1a;1. 物理层&#xff08;第1层&#xff09; 核心功能&a…

RSA-e和phi不互素

1.题目import gmpy2 import libnum p 1656713884642828937525841253265560295123546793973683682208576533764344166170780019002774068042673556637515136828403375582169041170690082676778939857272304925933251736030429644277439899845034340194709105071151095131704526…

基于单片机蒸汽压力检测/蒸汽余热回收

传送门 &#x1f449;&#x1f449;&#x1f449;&#x1f449;单片机作品题目速选一览表&#x1f680; &#x1f449;&#x1f449;&#x1f449;&#x1f449;单片机作品题目功能速览&#x1f680; &#x1f525;更多文章戳&#x1f449;小新单片机-CSDN博客&#x1f68…

https 协议与 wss 协议有什么不同

HTTPS 是用于网页数据传输的安全协议&#xff0c;而 WSS 是用于实时双向通信&#xff08;如聊天、直播&#xff09;的安全协议&#xff0c;二者的设计目标、应用场景、底层逻辑均存在本质区别。以下从 7 个核心维度展开对比&#xff0c;并补充关键关联知识&#xff0c;帮助彻底…

主流分布式数据库集群选型指南

以下是关于主流分布式可扩展数据库集群的详细解析&#xff0c;涵盖技术分类、代表产品及适用场景&#xff0c;帮助您高效选型&#xff1a;一、分布式数据库核心分类 1. NewSQL 数据库&#xff08;强一致性 分布式事务&#xff09;产品开发方核心特性适用场景TiDBPingCAPHTAP架…

#T1359. 围成面积

题目描述编程计算由“*”号围成的下列图形的面积。面积计算方法是统计*号所围成的闭合曲线中水平线和垂直线交点的数目。如下图所示&#xff0c;在1010的二维数组中&#xff0c;有“*”围住了15个点&#xff0c;因此面积为15。输入1010的图形。输出输出面积。样例输入数据 10 0…

Hive on Tez/Spark 执行引擎对比与优化

在大数据开发中,Hive 已经成为最常用的数据仓库工具之一。随着业务数据规模的不断扩大,Hive 默认的 MapReduce 执行引擎 显得笨重低效。为了提升查询性能,Hive 支持了 Tez 和 Spark 作为底层执行引擎。本文将带你对比 Hive on Tez 与 Hive on Spark 的区别,并分享调优经验。…

深入理解 Next.js 的路由机制

深入理解 Next.js 的路由机制 作者&#xff1a;码力无边在上一篇文章中&#xff0c;我们成功创建并运行了第一个 Next.js 应用。当你打开项目文件夹时&#xff0c;你可能会注意到一个名为 pages 的目录。这个目录看似普通&#xff0c;但它却是 Next.js 路由系统的核心。今天&am…