【高心星出品】

调整屏幕亮度

概述

在“视频播放”和“付款码展示”这两种典型场景下,应用需要在不同的页面分别设置不同的屏幕亮度,用户也可以自定义调节屏幕亮度,并且随着页面跳转而自动恢复系统亮度设置。

原理

当前亮度设置的能力由窗口提供,设置亮度后,如果没有再次修改,亮度将不会发生变化(仅在应用内生效,退出应用恢复系统默认亮度)。

窗口作为亮度设置的媒介,窗口的改变会使得该窗口下所有页面的亮度都跟随改变,所以需要一套记录页面和监听页面变化的机制,动态设置不同页面下的亮度。

视频播放页面亮度调节

场景描述

视频播放场景,支持用户在视频页调节屏幕亮度,调整完亮度退出页面后其他页面仍为系统亮度,再次进入视频页,屏幕亮度会自动恢复成页面之前保存的亮度。

开发步骤

调节屏幕亮度:

1.维护页面与亮度的映射关系

private static brightnessMap: Map<string, number> =
  new Map([[Constants.NAV_DESTINATION_DEFAULT, this.DEFAULT_BRIGHTNESS],
    [Constants.NAV_DESTINATION_ITEM_PAY_CODE, this.MAX_BRIGHTNESS]]);

代码逻辑走读:

  1. 定义了一个名为brightnessMap的静态私有成员变量。
  2. 使用Map构造函数初始化该变量,其中包含两个数组,每个数组包含一个键值对。
  3. 第一个数组的键是Constants.NAV_DESTINATION_DEFAULT,对应的值是this.DEFAULT_BRIGHTNESS
  4. 第二个数组的键是Constants.NAV_DESTINATION_ITEM_PAY_CODE,对应的值是this.MAX_BRIGHTNESS

2.在视频播放器组件上添加滑动组件Slider

build() {
  Stack({ alignContent: Alignment.Start }) {
    Video({
      src: $rawfile('video1.mp4'),
      previewUri: $r('app.media.img_preview'),
    })
      .loop(true)
      .width(Constants.FULL_PERCENT)
      .height(Constants.FULL_PERCENT)
      .onStart(() => {
        this.brightnessViewModel.setWindowKeepScreenState(true);
      })
      .onPause(() => {
        this.brightnessViewModel.setWindowKeepScreenState(false);
      })
    Slider({
      value: this.currentBrightness,
      min: 0,
      max: 1,
      step: 0.01,
      style: SliderStyle.InSet,
      direction: Axis.Vertical,
      reverse: true
    })
      .trackColor('#66A0A0A4')
      .blockColor(Color.Transparent)
      .selectedColor(Color.White)
      .height('80%')
      .margin({ left: 24, bottom: 24 })
      .onChange((value: number, mode: SliderChangeMode) => { // Slider onChange callback
        if (mode === SliderChangeMode.Moving) {
          this.sliderOpacity = 1;
          this.brightnessViewModel.updateVideoBrightness(value);
        } else if (mode === SliderChangeMode.End) {
          this.sliderOpacity = 0;
        }
      })
      .opacity(this.sliderOpacity)
      .animation({
        duration: 300
      })
  }
  .width(Constants.FULL_PERCENT)
  .height(184)
}

代码逻辑走读:

  1. 组件构建:使用build()函数定义UI组件的结构。
  2. 布局容器:使用Stack布局容器,设置内容对齐方式为Alignment.Start
  3. 视频播放:
    • 创建一个Video组件,指定视频源为video1.mp4,预览图为img_preview
    • 设置视频循环播放,宽度和高度为全屏(Constants.FULL_PERCENT)。
    • 当视频开始播放时,调用onStart回调,将屏幕状态设置为保持(true)。
    • 当视频暂停时,调用onPause回调,将屏幕状态设置为不保持(false)。
  4. 滑块组件:
    • 创建一个Slider组件,用于调整亮度,范围从0到1,步长为0.01。
    • 设置滑块的样式为垂直方向,反向显示。
    • 滑块的轨道颜色为#66A0A0A4,块颜色为透明,选中部分颜色为白色。
    • 滑块的高度为80%,底部和左侧的边距分别为24。
    • 当滑块值改变时,根据模式(移动或结束)调整滑块的不透明度,并更新视频亮度。
  5. 组件样式:
    • 设置组件的宽度和高度为全屏和184像素。

3.通过滑动组件调节屏幕亮度,并将调节的亮度值缓存

/**
 * Video playback page brightness adjustment execution function
 *
 * @param brightness Brightness value
 */
public static updateVideoBrightness(brightness: number): void {
  BrightnessUtil.setBrightness(brightness, Constants.SET_BRIGHTNESS_SLIDE);
  BrightnessUtil.brightnessMap.set(Constants.NAV_DESTINATION_ITEM_VIDEO, brightness);
}

代码逻辑走读:

  1. 方法定义:定义了一个名为 updateVideoBrightness的静态方法,该方法接受一个 brightness参数,类型为 number,表示亮度值。
  2. 亮度设置:调用 BrightnessUtil.setBrightness方法,传入 brightnessConstants.SET_BRIGHTNESS_SLIDE作为参数,用于设置视频播放页面的亮度。
  3. 亮度存储:将新的亮度值存储在 BrightnessUtil.brightnessMap中,键为 Constants.NAV_DESTINATION_ITEM_VIDEO,值为 brightness,以便后续使用。

4.返回首页,恢复屏幕默认亮度,重新进入视频播放页,恢复最后一次在视频播放页设置的亮度

// Switch and listen to the routing page, and set the brightness of the cached page.
private navDestinationUpdateCallBack: Callback<NavDestinationInfo> = (info: NavDestinationInfo): void => {
  switch (info.state) {
    case uiObserver.NavDestinationState.ON_SHOWN:
      BrightnessUtil.setBrightness(info.name as string, Constants.SET_BRIGHTNESS_CLICK);
      BrightnessUtil.setStateBarContentColor(info.name as string, '#FFFFFF');
      break;
    case uiObserver.NavDestinationState.ON_HIDDEN:
    case uiObserver.NavDestinationState.ON_BACKPRESS:
      BrightnessUtil.setBrightness(Constants.NAV_DESTINATION_DEFAULT, Constants.SET_BRIGHTNESS_CLICK);
      BrightnessUtil.setStateBarContentColor(info.name as string, '#000000');
      break;
    default:
      break;
  }
};

public registerNavigationListener(): void {
  uiObserver.on('navDestinationUpdate', this.navDestinationUpdateCallBack);
}

public unRegisterNavigationListener(): void {
  uiObserver.off('navDestinationUpdate', this.navDestinationUpdateCallBack);
}

代码逻辑走读:

  1. 定义了一个名为navDestinationUpdateCallBack的回调函数,该函数根据导航页面的状态(info.state)来设置页面的亮度和状态栏的内容颜色。
  2. 当导航页面显示时(ON_SHOWN状态),调用BrightnessUtilsetBrightness方法设置页面的亮度为Constants.SET_BRIGHTNESS_CLICK,并使用setStateBarContentColor方法将状态栏的内容颜色设置为白色(#FFFFFF)。
  3. 当导航页面隐藏或返回时(ON_HIDDENON_BACKPRESS状态),调用BrightnessUtilsetBrightness方法将页面的亮度设置为默认值Constants.NAV_DESTINATION_DEFAULT,并将状态栏的内容颜色设置为黑色(#000000)。
  4. 定义了一个registerNavigationListener方法,用于注册导航目的地更新的监听器,即当导航目的地更新时,调用navDestinationUpdateCallBack回调函数。
  5. 定义了一个unRegisterNavigationListener方法,用于注销导航目的地更新的监听器,防止在不需要时继续接收通知。

实现效果

图1 视频播放页面

在这里插入图片描述

视频播放时页面常亮设置

场景描述

视频播放场景,在视频播放期间,即使用户没有屏幕交互操作,也希望保持屏幕常亮,直至视频播放完成或退出视频播放页。

开发步骤

1.视频播放时保持屏幕常亮,暂停或退出页面,取消屏幕常亮

Video({
  src: $rawfile('video1.mp4'),
  previewUri: $r('app.media.img_preview'),
})
  .loop(true)
  .width(Constants.FULL_PERCENT)
  .height(Constants.FULL_PERCENT)
  .onStart(() => {
    this.brightnessViewModel.setWindowKeepScreenState(true);
  })
  .onPause(() => {
    this.brightnessViewModel.setWindowKeepScreenState(false);
  })

代码逻辑走读:

  1. 创建视频组件:通过Video构造函数初始化一个视频播放组件。
  2. 设置视频源:使用src属性指定视频文件的路径,这里使用了$rawfile函数从项目资源中加载video1.mp4
  3. 设置预览图像:使用previewUri属性指定视频播放前的预览图像,这里使用了$r函数从项目资源中加载img_preview
  4. 设置循环播放:调用loop(true)方法设置视频为循环播放。
  5. 设置播放区域:通过widthheight属性将视频播放区域设置为全屏(使用Constants.FULL_PERCENT表示)。
  6. 监听播放开始事件:使用onStart方法注册播放开始时的回调函数,当视频开始播放时,调用brightnessViewModel.setWindowKeepScreenState(true)保持屏幕状态。
  7. 监听播放暂停事件:使用onPause方法注册播放暂停时的回调函数,当视频暂停时,调用brightnessViewModel.setWindowKeepScreenState(false)恢复屏幕状态。

2.设置屏幕常亮接口

/**
 * Keep screen brightness
 *
 * @param isKeepOn true:keep;false:cancel keep
 */
public static setWindowKeepScreenState(isKeepOn: boolean): void {
  try {
    BrightnessUtil.windowClass?.setWindowKeepScreenOn(isKeepOn, (err: BusinessError) => {
      const errCode: number = err.code;
      if (errCode) {
        hilog.error(0x0000, TAG, `Failed set window keep screen state, errorCode: ${err.code}`);
        return;
      }
      hilog.info(0x0000, TAG, `Success set window keep screen state`);
    });
  } catch (err) {
    hilog.error(0x0000, TAG, `Failed set window keep screen state, errorCode: ${err.code}`);
  }
}

代码逻辑走读:

  1. 方法定义与参数说明
    • 方法名为 setWindowKeepScreenState,接受一个布尔类型的参数 isKeepOn,用于指示是否保持屏幕常亮。
  2. 错误处理机制
    • 使用 try-catch块来捕获可能的异常。
    • try块中,调用 BrightnessUtil.windowClass?.setWindowKeepScreenOn方法,传入 isKeepOn和一个回调函数。
  3. 回调函数逻辑
    • 回调函数接收一个 BusinessError类型的参数 err
    • 检查 err.code,如果存在错误码,记录错误日志并返回。
    • 如果没有错误码,记录成功日志。
  4. 异常处理
    • 如果在 try块中抛出异常,捕获异常并记录错误日志。

付款码页面高亮设置

场景描述

一些包含支付功能的应用,用户进入付款码页面,应用自动设置屏幕最高亮度,退出付款码页面,恢复屏幕默认亮度。

开发步骤

1.内存中维护一个页面与亮度的映射关系

private static brightnessMap: Map<string, number> =
  new Map([[Constants.NAV_DESTINATION_DEFAULT, this.DEFAULT_BRIGHTNESS],
    [Constants.NAV_DESTINATION_ITEM_PAY_CODE, this.MAX_BRIGHTNESS]]);

代码逻辑走读:

  1. 定义了一个名为brightnessMap的静态私有成员变量。
  2. 使用Map构造函数初始化该变量,其中包含两个数组,每个数组包含一个键值对。
  3. 第一个数组的键是Constants.NAV_DESTINATION_DEFAULT,对应的值是this.DEFAULT_BRIGHTNESS
  4. 第二个数组的键是Constants.NAV_DESTINATION_ITEM_PAY_CODE,对应的值是this.MAX_BRIGHTNESS

2.监听页面切换事件,进入付款码页面,设置高亮,返回首页,恢复屏幕默认亮度

// Switch and listen to the routing page, and set the brightness of the cached page.
private navDestinationUpdateCallBack: Callback<NavDestinationInfo> = (info: NavDestinationInfo): void => {
  switch (info.state) {
    case uiObserver.NavDestinationState.ON_SHOWN:
      BrightnessUtil.setBrightness(info.name as string, Constants.SET_BRIGHTNESS_CLICK);
      BrightnessUtil.setStateBarContentColor(info.name as string, '#FFFFFF');
      break;
    case uiObserver.NavDestinationState.ON_HIDDEN:
    case uiObserver.NavDestinationState.ON_BACKPRESS:
      BrightnessUtil.setBrightness(Constants.NAV_DESTINATION_DEFAULT, Constants.SET_BRIGHTNESS_CLICK);
      BrightnessUtil.setStateBarContentColor(info.name as string, '#000000');
      break;
    default:
      break;
  }
};

public registerNavigationListener(): void {
  uiObserver.on('navDestinationUpdate', this.navDestinationUpdateCallBack);
}

public unRegisterNavigationListener(): void {
  uiObserver.off('navDestinationUpdate', this.navDestinationUpdateCallBack);
}

代码逻辑走读:

  1. 定义了一个名为navDestinationUpdateCallBack的回调函数,该函数根据导航页面的状态(info.state)来设置页面的亮度和状态栏的内容颜色。
  2. 当导航页面显示时(ON_SHOWN状态),调用BrightnessUtilsetBrightness方法设置页面的亮度为Constants.SET_BRIGHTNESS_CLICK,并使用setStateBarContentColor方法将状态栏的内容颜色设置为白色(#FFFFFF)。
  3. 当导航页面隐藏或返回时(ON_HIDDENON_BACKPRESS状态),调用BrightnessUtilsetBrightness方法将页面的亮度设置为默认值Constants.NAV_DESTINATION_DEFAULT,并将状态栏的内容颜色设置为黑色(#000000)。
  4. 定义了一个registerNavigationListener方法,用于注册导航目的地更新的监听器,即当导航目的地更新时,调用navDestinationUpdateCallBack回调函数。
  5. 定义了一个unRegisterNavigationListener方法,用于注销导航目的地更新的监听器,防止不必要的回调函数调用。

实现效果

图2 付款码页面

在这里插入图片描述

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐