HarmonyOS 鸿蒙Next换肤功能怎么实现
HarmonyOS 鸿蒙Next换肤功能怎么实现
深浅色模式目前有以下不足:
1.只支持深浅色两种模式的切换,对于需要多个主题的场景不能满足。
2.image组件(除了svg这种支持.fillColor()的)目前不支持深浅色模式的热加载,想要实现按钮图标的切换可能还是需要使用三元表达式,对于图标多的场景不够方便
优点:系统规范较好
主题类实现深浅色模式有以下不足:
1.重新渲染ui的性能没有保障,还需要测试
2.资源都继承在一个文件里,如果是很大的工程可能比较难管理
3.相关代码规范问题
优点: 可以支持多种主题的切换,只需要加切换函数就够了 支持按钮图标,图片热加载,支持多种资源根据主题切换,并实时重新渲染 在page中引用资源和传统方式的代码量差不多,能比较方便的使用,使用方法简单快捷
参考demo:
Index.ets
import theme from '../pages/theme'
struct Index {
@State message: string = ‘normal mode’;
@StorageLink(‘current mode’) current_mode: string = ‘normal_mode’
@StorageLink(‘main_theme’) theme: theme = new theme(this.current_mode)
@StorageLink(‘gray mode’) gray_mode: number = 0;
build() {
Column() {
Row() {
Text(<span class="hljs-keyword">this</span>.message)
.fontSize(<span class="hljs-number">50</span>)
.fontColor(<span class="hljs-keyword">this</span>.theme.text_color)
.fontWeight(FontWeight.Bold)
}.justifyContent(FlexAlign.Center)
.width(<span class="hljs-string">'100%'</span>)
Row() {
Column() {
Image(<span class="hljs-keyword">this</span>.theme.phone_icon).objectFit(ImageFit.Contain)
Text(<span class="hljs-string">'电话'</span>).fontColor(<span class="hljs-keyword">this</span>.theme.text_color)
Image(<span class="hljs-keyword">this</span>.theme.camera_icon).objectFit(ImageFit.Contain)
Text(<span class="hljs-string">'相机'</span>).fontColor(<span class="hljs-keyword">this</span>.theme.text_color)
}.width(<span class="hljs-string">'22%'</span>).height(<span class="hljs-number">90</span>)
}.width(<span class="hljs-string">'100%'</span>).alignItems(VerticalAlign.Top).height(<span class="hljs-string">'250vp'</span>).justifyContent(FlexAlign.SpaceEvenly)
Row() {
Button(<span class="hljs-string">'color mode'</span>)
.width(<span class="hljs-string">'30%'</span>)
.fontColor(<span class="hljs-keyword">this</span>.theme.text_color)
.onClick(() => {
<span class="hljs-keyword">this</span>.message = <span class="hljs-string">'color mode'</span>
<span class="hljs-keyword">this</span>.theme.color_mode()
<span class="hljs-keyword">this</span>.current_mode = <span class="hljs-string">'color_mode'</span>
})
Button(<span class="hljs-string">'normal mode'</span>)
.width(<span class="hljs-string">'30%'</span>)
.fontColor(<span class="hljs-keyword">this</span>.theme.text_color)
.onClick(() => {
<span class="hljs-keyword">this</span>.message = <span class="hljs-string">'normal mode'</span>
<span class="hljs-keyword">this</span>.theme.normal_mode()
<span class="hljs-keyword">this</span>.current_mode = <span class="hljs-string">'normal_mode'</span>
})
Button(<span class="hljs-string">'simple mode'</span>)
.width(<span class="hljs-string">'30%'</span>)
.fontColor(<span class="hljs-keyword">this</span>.theme.text_color)
.onClick(() => {
<span class="hljs-keyword">this</span>.message = <span class="hljs-string">'simple mode'</span>
<span class="hljs-keyword">this</span>.theme.simple_mode()
<span class="hljs-keyword">this</span>.current_mode = <span class="hljs-string">'simple_mode'</span>
})
}.height(<span class="hljs-number">50</span>)
.justifyContent(FlexAlign.SpaceAround)
.width(<span class="hljs-string">'100%'</span>)
Image($r(<span class="hljs-string">'app.media.find_service'</span>)).objectFit(ImageFit.Contain).height(<span class="hljs-number">200</span>)
<span class="hljs-comment">// 整体UI变灰色</span>
Row() {
Button(<span class="hljs-string">'gray mode off'</span>).fontColor(<span class="hljs-keyword">this</span>.theme.text_color).height(<span class="hljs-string">'30vp'</span>).onClick(() => <span class="hljs-keyword">this</span>.gray_mode = <span class="hljs-number">0</span>)
Button(<span class="hljs-string">'gray mode on'</span>).fontColor(<span class="hljs-keyword">this</span>.theme.text_color).height(<span class="hljs-string">'30vp'</span>).onClick(() => <span class="hljs-keyword">this</span>.gray_mode = <span class="hljs-number">1</span>)
}
}
.grayscale(<span class="hljs-keyword">this</span>.gray_mode)
.height(<span class="hljs-string">'100%'</span>).backgroundColor(<span class="hljs-keyword">this</span>.theme.background_color)
}
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
theme.ets
export default class theme {
//资源目录,将需要实现主题切换的资源变量存储在这
current_mode: string = ‘normal_mode’
earphone_icon: Resource = $r(‘app.media.ic_device_earphone_hero_filled’)
home_icon: Resource = $r(‘app.media.ic_public_home_filled’)
picture_icon: Resource = $r(‘app.media.ic_public_picture_filled’)
folder_icon: Resource = $r(‘app.media.ic_public_folder_filled’)
icon2: Resource = $r(‘app.media.ic_public_picture’)
color1: Resource = $r(‘app.color.red’)
font_color: Resource = $r(‘app.color.black’)
text_color: Resource = $r(‘app.color.black’)
background_color: Resource = $r(‘app.color.white’)
phone_icon: Resource = $r(‘app.media.dialer’)
market_icon: Resource = $r(‘app.media.shopping’)
notes_icon: Resource = $r(‘app.media.notes’)
setting_icon: Resource = $r(‘app.media.settings’)
camera_icon: Resource = $r(‘app.media.camera’)
photos_icon: Resource = $r(‘app.media.gallery’)
music_icon: Resource = $r(‘app.media.music’)
video_icon: Resource = $r(‘app.media.video’)
//通过读取current mode实现在重启应用后可以保存应用主题数据
constructor(current_mode: string) {
<span class="hljs-keyword">switch</span> (current_mode) {
<span class="hljs-keyword">case</span> <span class="hljs-string">'normal_mode'</span>:
<span class="hljs-keyword">this</span>.background_color = $r(<span class="hljs-string">'app.color.background'</span>)
<span class="hljs-keyword">this</span>.text_color = $r(<span class="hljs-string">'app.color.brown'</span>)
<span class="hljs-keyword">this</span>.phone_icon = $r(<span class="hljs-string">'app.media.dialer'</span>)
<span class="hljs-keyword">this</span>.market_icon = $r(<span class="hljs-string">'app.media.shopping'</span>)
<span class="hljs-keyword">this</span>.notes_icon = $r(<span class="hljs-string">'app.media.notes'</span>)
<span class="hljs-keyword">this</span>.setting_icon = $r(<span class="hljs-string">'app.media.settings'</span>)
<span class="hljs-keyword">this</span>.camera_icon = $r(<span class="hljs-string">'app.media.camera'</span>)
<span class="hljs-keyword">this</span>.photos_icon = $r(<span class="hljs-string">'app.media.gallery'</span>)
<span class="hljs-keyword">this</span>.music_icon = $r(<span class="hljs-string">'app.media.music'</span>)
<span class="hljs-keyword">this</span>.video_icon = $r(<span class="hljs-string">'app.media.video'</span>)
<span class="hljs-keyword">break</span>;
<span class="hljs-keyword">case</span> <span class="hljs-string">'color_mode'</span>:
<span class="hljs-keyword">this</span>.background_color = $r(<span class="hljs-string">'app.color.color_background'</span>)
<span class="hljs-keyword">this</span>.text_color = $r(<span class="hljs-string">'app.color.yellow'</span>)
<span class="hljs-keyword">this</span>.phone_icon = $r(<span class="hljs-string">'app.media.pwcall'</span>)
<span class="hljs-keyword">this</span>.market_icon = $r(<span class="hljs-string">'app.media.pwshop'</span>)
<span class="hljs-keyword">this</span>.notes_icon = $r(<span class="hljs-string">'app.media.pwnotes'</span>)
<span class="hljs-keyword">this</span>.setting_icon = $r(<span class="hljs-string">'app.media.pwsetting'</span>)
<span class="hljs-keyword">this</span>.camera_icon = $r(<span class="hljs-string">'app.media.pwcamera'</span>)
<span class="hljs-keyword">this</span>.photos_icon = $r(<span class="hljs-string">'app.media.pwphotos'</span>)
<span class="hljs-keyword">this</span>.music_icon = $r(<span class="hljs-string">'app.media.pwmusic'</span>)
<span class="hljs-keyword">this</span>.video_icon = $r(<span class="hljs-string">'app.media.pwvideo'</span>)
<span class="hljs-keyword">break</span>;
<span class="hljs-keyword">case</span> <span class="hljs-string">'simple_mode'</span>:
<span class="hljs-keyword">this</span>.background_color = $r(<span class="hljs-string">'app.color.white'</span>)
<span class="hljs-keyword">this</span>.text_color = $r(<span class="hljs-string">'app.color.black'</span>)
<span class="hljs-keyword">this</span>.phone_icon = $r(<span class="hljs-string">'app.media.simplicityCall'</span>)
<span class="hljs-keyword">this</span>.market_icon = $r(<span class="hljs-string">'app.media.simplicityShop'</span>)
<span class="hljs-keyword">this</span>.notes_icon = $r(<span class="hljs-string">'app.media.simplicityNotes'</span>)
<span class="hljs-keyword">this</span>.setting_icon = $r(<span class="hljs-string">'app.media.simplicitySetting'</span>)
<span class="hljs-keyword">this</span>.camera_icon = $r(<span class="hljs-string">'app.media.simplicityCamera'</span>)
<span class="hljs-keyword">this</span>.photos_icon = $r(<span class="hljs-string">'app.media.simplicityPhotos'</span>)
<span class="hljs-keyword">this</span>.music_icon = $r(<span class="hljs-string">'app.media.simplicityMusic'</span>)
<span class="hljs-keyword">this</span>.video_icon = $r(<span class="hljs-string">'app.media.simplicityVideo'</span>)
<span class="hljs-keyword">break</span>;
<span class="hljs-keyword">default</span>:
<span class="hljs-keyword">this</span>.current_mode = <span class="hljs-string">'normal_mode'</span>
<span class="hljs-keyword">this</span>.background_color = $r(<span class="hljs-string">'app.color.background'</span>)
<span class="hljs-keyword">this</span>.text_color = $r(<span class="hljs-string">'app.color.brown'</span>)
<span class="hljs-keyword">this</span>.phone_icon = $r(<span class="hljs-string">'app.media.dialer'</span>)
<span class="hljs-keyword">this</span>.market_icon = $r(<span class="hljs-string">'app.media.shopping'</span>)
<span class="hljs-keyword">this</span>.notes_icon = $r(<span class="hljs-string">'app.media.notes'</span>)
<span class="hljs-keyword">this</span>.setting_icon = $r(<span class="hljs-string">'app.media.settings'</span>)
<span class="hljs-keyword">this</span>.camera_icon = $r(<span class="hljs-string">'app.media.camera'</span>)
<span class="hljs-keyword">this</span>.photos_icon = $r(<span class="hljs-string">'app.media.gallery'</span>)
<span class="hljs-keyword">this</span>.music_icon = $r(<span class="hljs-string">'app.media.music'</span>)
<span class="hljs-keyword">this</span>.video_icon = $r(<span class="hljs-string">'app.media.video'</span>)
<span class="hljs-keyword">break</span>;
}
}
//通过不同的主题切换函数更改主题变量,并在外部通过Appstorage实现应用内共享和画面重现渲染
light_mode() {
<span class="hljs-keyword">this</span>.font_color = $r(<span class="hljs-string">'app.color.black'</span>)
<span class="hljs-keyword">this</span>.background_color = $r(<span class="hljs-string">'app.color.white'</span>)
<span class="hljs-keyword">this</span>.earphone_icon = $r(<span class="hljs-string">'app.media.ic_device_earphone_hero_filled'</span>)
<span class="hljs-keyword">this</span>.home_icon = $r(<span class="hljs-string">'app.media.ic_public_home_filled'</span>)
<span class="hljs-keyword">this</span>.picture_icon = $r(<span class="hljs-string">'app.media.ic_public_picture_filled'</span>)
<span class="hljs-keyword">this</span>.folder_icon = $r(<span class="hljs-string">'app.media.ic_public_folder_filled'</span>)
}
dark_mode() {
<span class="hljs-keyword">this</span>.font_color = $r(<span class="hljs-string">'app.color.white'</span>)
<span class="hljs-keyword">this</span>.background_color = $r(<span class="hljs-string">'app.color.background'</span>)
<span class="hljs-keyword">this</span>.earphone_icon = $r(<span class="hljs-string">'app.media.ic_device_earphone_hero'</span>)
<span class="hljs-keyword">this</span>.home_icon = $r(<span class="hljs-string">'app.media.ic_public_home'</span>)
<span class="hljs-keyword">this</span>.picture_icon = $r(<span class="hljs-string">'app.media.ic_public_picture'</span>)
<span class="hljs-keyword">this</span>.folder_icon = $r(<span class="hljs-string">'app.media.ic_public_folder'</span>)
}
normal_mode() {
<span class="hljs-keyword">this</span>.current_mode = <span class="hljs-string">'normal_mode'</span>
<span class="hljs-keyword">this</span>.background_color = $r(<span class="hljs-string">'app.color.background'</span>)
<span class="hljs-keyword">this</span>.text_color = $r(<span class="hljs-string">'app.color.brown'</span>)
<span class="hljs-keyword">this</span>.phone_icon = $r(<span class="hljs-string">'app.media.dialer'</span>)
<span class="hljs-keyword">this</span>.market_icon = $r(<span class="hljs-string">'app.media.shopping'</span>)
<span class="hljs-keyword">this</span>.notes_icon = $r(<span class="hljs-string">'app.media.notes'</span>)
<span class="hljs-keyword">this</span>.setting_icon = $r(<span class="hljs-string">'app.media.settings'</span>)
<span class="hljs-keyword">this</span>.camera_icon = $r(<span class="hljs-string">'app.media.camera'</span>)
<span class="hljs-keyword">this</span>.photos_icon = $r(<span class="hljs-string">'app.media.gallery'</span>)
<span class="hljs-keyword">this</span>.music_icon = $r(<span class="hljs-string">'app.media.music'</span>)
<span class="hljs-keyword">this</span>.video_icon = $r(<span class="hljs-string">'app.media.video'</span>)
}
color_mode() {
<span class="hljs-keyword">this</span>.current_mode = <span class="hljs-string">'color_mode'</span>
<span class="hljs-keyword">this</span>.background_color = $r(<span class="hljs-string">'app.color.color_background'</span>)
<span class="hljs-keyword">this</span>.text_color = $r(<span class="hljs-string">'app.color.yellow'</span>)
<span class="hljs-keyword">this</span>.phone_icon = $r(<span class="hljs-string">'app.media.pwcall'</span>)
<span class="hljs-keyword">this</span>.market_icon = $r(<span class="hljs-string">'app.media.pwshop'</span>)
<span class="hljs-keyword">this</span>.notes_icon = $r(<span class="hljs-string">'app.media.pwnotes'</span>)
<span class="hljs-keyword">this</span>.setting_icon = $r(<span class="hljs-string">'app.media.pwsetting'</span>)
<span class="hljs-keyword">this</span>.camera_icon = $r(<span class="hljs-string">'app.media.pwcamera'</span>)
<span class="hljs-keyword">this</span>.photos_icon = $r(<span class="hljs-string">'app.media.pwphotos'</span>)
<span class="hljs-keyword">this</span>.music_icon = $r(<span class="hljs-string">'app.media.pwmusic'</span>)
<span class="hljs-keyword">this</span>.video_icon = $r(<span class="hljs-string">'app.media.pwvideo'</span>)
}
simple_mode() {
<span class="hljs-keyword">this</span>.current_mode = <span class="hljs-string">'simple_mode'</span>
<span class="hljs-keyword">this</span>.background_color = $r(<span class="hljs-string">'app.color.white'</span>)
<span class="hljs-keyword">this</span>.text_color = $r(<span class="hljs-string">'app.color.black'</span>)
<span class="hljs-keyword">this</span>.phone_icon = $r(<span class="hljs-string">'app.media.simplicityCall'</span>)
<span class="hljs-keyword">this</span>.market_icon = $r(<span class="hljs-string">'app.media.simplicityShop'</span>)
<span class="hljs-keyword">this</span>.notes_icon = $r(<span class="hljs-string">'app.media.simplicityNotes'</span>)
<span class="hljs-keyword">this</span>.setting_icon = $r(<span class="hljs-string">'app.media.simplicitySetting'</span>)
<span class="hljs-keyword">this</span>.camera_icon = $r(<span class="hljs-string">'app.media.simplicityCamera'</span>)
<span class="hljs-keyword">this</span>.photos_icon = $r(<span class="hljs-string">'app.media.simplicityPhotos'</span>)
<span class="hljs-keyword">this</span>.music_icon = $r(<span class="hljs-string">'app.media.simplicityMusic'</span>)
<span class="hljs-keyword">this</span>.video_icon = $r(<span class="hljs-string">'app.media.simplicityVideo'</span>)
}
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
在resource目录下创建了dark/element目录、dark/media目录。element创建 color.json资源 ,在 media中 存放图片资源。适配手机深色模式。
更多关于HarmonyOS 鸿蒙Next换肤功能怎么实现的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html