在app中适配深色模式及切换深色模式 原创

在敲键盘的小鱼干很饥饿
发布于 2024-12-26 17:09
浏览
0收藏

1. 效果展示

2. 概述

在开发应用中,深色模式逐渐成为用户界面设计的重要组成部分。如果不在开发时,主动配置颜色资源来设置深色模式,这样在系统切换深色模式后,再次打开咱们的应用就会很丑。深色模式的实现方式,包括跟随系统变化和不跟随系统变化的两种场景。下面我就来介绍一下这两部分

3. 跟随系统变化

3.1 不设置深色模式

应用默认是跟随系统的颜色变化的,如果不想跟随系统颜色变化,不设置深色模式,避免系统深色模式给app的影响,就可以在应用的entryability中

onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
   this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
}

将枚举值COLOR_MODE_NOT_SET(未配置颜色模式)改为浅色模式

this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_LIGHT)

但是我们开发应用,肯定想让用户又更好的体验,所以最好还是要适配深色模式的。下面我就来详细解释怎么跟随系统设置深色模式

3.2 颜色资源适配

在工程的resources/dark/element/color.json和resources/base/element/color.json下面需要我的自己定义一些颜色资源的适配。

3.2.1 基于资源文件的组件颜色适配

示例
在base中适配浅色资源

{
  "color": [
    {
      "name": "start_window_background",
      "value": "#FFFFFF"
    },
    {
      "name": "background_color",
      "value": "#F5F5F5",
      "additionalProperties": "全局背景颜色"
    },
    {
      "name": "font_color",
      "value": "#BEFF33",
      "additionalProperties": "全局绿色文字"
    },
    {
      "name": "main_font",
      "value": "#000000",
      "additionalProperties": "全局主字体颜色"
    },
      ]
}

在dark中适配深色资源

{
  "color": [
    {
      "name": "start_window_background",
      "value": "#000000"
    },
    {
      "name": "background_color",
      "value": "#121212",
      "additionalProperties": "全局背景颜色"
    },
    {
      "name": "font_color",
      "value": "#6B8E1D",
      "additionalProperties": "全局绿色文字"
    },
    {
      "name": "main_font",
      "value": "#F6F6F6",
      "additionalProperties": "全局主字体颜色"
    },
       ]
}

这样我的就可以在开发中使用他们了,通过$r方式加载颜色资源的key值

@Entry
@Component
struct MyComponent {
  build() {
    Column() {
      Text('Hello, World!')
        .backgroundColor($r('app.color.background_color'))
    }
  }
}

3.2.2 基于媒体文件的图片资源适配

在resources/base/media和resources/dark/media中分别存放浅色和深色模式下的图片资源
对于png图片
示例

@Entry
@Component
struct Button{
  build() {
    Column() {
      Image($r("app.media.add"))
    }
  }
}

对于svg图片
通过fillColor属性配合系统资源改变图片的绘制颜色。
示例

Image($r(modeImgMap.get(item.mode)))
        .width(28)
        .height(28)
        .margin({ left: 10, right: 10 })
        .fillColor(this.selectedTravelModeIndex === index ? '#5B5B5B' : $r('app.color.menu_font_color'))

3.2.3 基于Web组件适配

通过darkMode和forceDarkAccess属性配置Web组件的深色模式。

import web_webview from '@ohos.web.webview'

@Entry
@Component
struct MyComponent{
  controller: web_webview.WebviewController = new web_webview.WebviewController()
  @State mode: WebDarkMode = WebDarkMode.Auto
  @State access: boolean = true

  build() {
    Column() {
      Web({ src: 'www.baidu.com', controller: this.controller })
        .darkMode(this.mode)
        .forceDarkAccess(this.access)
    }
  }
}

4. 不跟随系统变化

4.1 通过setColorMode设置应用的颜色模式(自定义按钮更改)

我们可以在应用中自定义按钮来改变app的颜色模式,以便用户可以获得更佳的体验
上面的颜色资源适配还是老样子
示例

@Entry
@Component
export struct MyPage {
  private context = getContext(this) as common.UIAbilityContext
  @State isDarkMode: boolean = this.context.config.colorMode ? false : true;	
  build() {
     Toggle({ type: ToggleType.Switch, isOn: this.isDarkMode })
           .width(41)
           .height(21)
           .switchStyle({
          	unselectedColor: '#FFFFFF',
      		pointRadius: 9
        	})
           .switchPointColor('#333333')
           .selectedColor('#E9FAFF')
           .borderRadius(25)
           .border({ color: '#333333', width: 1 })
           .margin({ right: 25 })
           .onChange(() => {
            //深色模式切换
             this.isDarkMode = !this.isDarkMode;
             this.context.getApplicationContext().setColorMode(this.isDarkMode ? 0 : 1);
         });
  }
}

在app中适配深色模式及切换深色模式-鸿蒙开发者社区
当用户开关 Toggle 控件时,会触发 onChange 事件,代码中会更新 isDarkMode 状态变量的值,并调用 context.getApplicationContext().setColorMode() 方法来改变应用的颜色模式。

  • 如果 isDarkMode 为 true,则设置颜色模式为 1(深色模式)。
  • 如果 isDarkMode 为 false,则设置颜色模式为 0(浅色模式)。
    这样就可以在应用中自己更改深色模式,无需跟随系统了

4.2 系统默认判断规则

  1. 如果应用调用上述setColorMode接口主动设置了深浅色,则以接口效果优先。
  2. 应用没有调用setColorMode接口时:
    • 如果应用工程dark目录下有深色资源,则系统内置组件在深色模式下会自动切换成为深色。
    • 如果应用工程dark目录下没有任何深色资源,则系统内置组件在深色模式下仍会保持浅色体验。

5. 总结

在ArkUI框架中实现深色模式适配是一个重要的任务,它能够显著提升用户在不同环境下的使用体验。我们介绍了两种实现深色模式的方式:跟随系统变化和不跟随系统变化。跟随系统变化时,可以通过设置颜色模式为 COLOR_MODE_NOT_SET 来确保应用自动适应系统设置,或者定义 resources/base/element/color.json 和 resources/dark/element/color.json 中的不同颜色资源,并分别准备浅色和深色模式下的图片资源。不跟随系统变化时,可以通过自定义按钮和 Toggle 控件来让用户手动切换颜色模式,并在 onChange 事件中更新颜色模式状态,确保应用能够根据用户的选择动态调整界面的颜色和图片资源。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2024-12-26 17:09:29修改
收藏
回复
举报
回复
    相关推荐