HarmonyOS应用开发:状态栏动画实现

前言

本案例展示了状态栏的动态交互效果。通过监听页面滚动事件 onDidScroll,随着页面的上下滚动,实现状态栏颜色的变化。搜索框会在滚动时流畅地展开或收起,并伴有自然的透明度过渡效果。

效果图预览

使用说明

  1. 进入页面开始加载,加载完成后显示整个界面,上下滚动页面即可。

实现思路

  • 初始化和状态设置

    aboutToAppear() 方法中,初始化了窗口模型 windowModel。启用沉浸式(设置全屏显示和状态栏为白色),获取状态栏高度存储在 statusBarHeight 变量中,从预定义的数据源 LIST_DATA 加载数据到 dataSource中。

    kotlin 复制代码
    aboutToAppear(): void {
      // 初始化窗口管理model
      const windowStage: window.WindowStage | undefined = AppStorage.get('windowStage');
      // 没有windowStage将无法执行下列逻辑
      if (!windowStage) {
        logger.error(TAG, 'windowStage init error!');
        return;
      }
      this.windowModel.setWindowStage(windowStage);
      // 设置沉浸模式及状态栏白色
      this.windowModel.setImmersive();
      // 获取顶部状态栏高度
      this.windowModel.getStatusBarHeight((statusBarHeight) => {
        logger.info(TAG, 'statusBarHeight is ' + statusBarHeight);
        this.statusBarHeight = px2vp(statusBarHeight);
      })
      // 组装数据源
      this.dataSource.pushArrayData(LIST_DATA)
    }
  • 界面布局构造

    使用Stack控件使状态栏与列表重叠,并为列表添加滚动监听器,以根据滚动位置调整状态栏和导航栏的透明度及展开收起动效。

    scss 复制代码
    Stack({ alignContent: Alignment.Top }) {
      Row() {
        // 动态显示回顶部或位置天气控件
        if (this.isFlow) {
          this.topUpBuilder()
        } else {
          this.locationAndWeatherBuilder()
        }
        this.searchViewBuilder()
        this.toolViewBuilder()
      }
      .height(Constants.NAVIGATION_BAR_HEIGHT + this.statusBarHeight)
        .width(Constants.FULL_PERCENT)
        .padding({
          top: this.statusBarHeight
        })
        .zIndex(Constants.Z_INDEX_THREE)
    
      // TODO: 知识点:父组件的透明度Opacity影响子组件(如父类Opacity为0.5,若子组件为0.5时,子组件实际Opacity = 0.5*0.5),此处Row来改变状态栏的透明度不受影响其它组件透明度
      Row() {
      }
      .backgroundColor($r("app.color.status_bar_animation_white"))
        .opacity(this.navigateBarOpacity)
        .height(Constants.STATUS_BAR_HEIGHT + this.statusBarHeight)
        .width(Constants.FULL_PERCENT)
        .zIndex(Constants.Z_INDEX_TWO)
    
      List({ scroller: this.scroller }) {
        // ...
      }
      // 隐藏滚动条
      .scrollBar(BarState.Off)
        // 渐变蓝色背景色
        .linearGradient({
          colors: [[Constants.LIST_LINEAR_GRADIENT_START_COLOR, Constants.LIST_LINEAR_GRADIENT_START],
            [Constants.LIST_LINEAR_GRADIENT_END_COLOR, Constants.LIST_LINEAR_GRADIENT_END]]
        })
        .height(Constants.FULL_PERCENT)
        .width(Constants.FULL_PERCENT)
    }
    .zIndex(Constants.Z_INDEX_ONE)
      .height(Constants.FULL_PERCENT)
      .width(Constants.FULL_PERCENT)
        // 扩展至所有非安全区域
      .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
  • 滚动事件处理

    通过监听页面滚动事件 onDidScroll,根据当前的滚动偏移量 yOffset 调整状态栏和导航栏的透明度。如果滚动超过了设定的阈值,则改变状态栏的颜色和展开收起动画。

    kotlin 复制代码
    .onDidScroll(() => {
      // TODO: 知识点:通过currentOffset来获取偏移量比较准确。
      const yOffset: number = this.scroller.currentOffset().yOffset;
      yOffset <= Constants.MAIN_SCROLLER_OFFSET_Y_ZERO ? this.negativeOffsetY = yOffset :
      Constants.MAIN_SCROLLER_OFFSET_Y_ZERO;
      // 判断导航栏和状态栏背景透明度变化
      yOffset >= Constants.MAIN_SCROLLER_OFFSET_Y_MAX + this.statusBarHeight ?
        this.navigateBarOpacity = Constants.NAVIGATION_BAR_OPACITY_MAX :
        this.navigateBarOpacity = Constants.NAVIGATION_BAR_OPACITY_MIN;
      this.navigateBarOpacity = yOffset / Constants.MAIN_SCROLLER_OFFSET_Y_MAX;
      // 判断当前的导航栏和图标颜色变化
      yOffset > this.statusBarHeight ?
        this.isWhiteColor = false : this.isWhiteColor = true;
      // 判断状态栏字体颜色变化
      yOffset > this.statusBarHeight ?
      this.windowModel.setSystemBarContentColor(Constants.StatusBarContentBlackColor) :
      this.windowModel.setSystemBarContentColor(Constants.StatusBarContentWhiteColor);
      // 判断导航栏动效变化
      yOffset >= this.statusBarHeight + Constants.MAIN_SCROLLER_OFFSET_STATUS_CHANGE ?
        this.isFlow = true : this.isFlow = false;
    })

总结

本示例使用了LazyForEach进行数据懒加载,LazyForEach懒加载可以通过设置cachedCount属性来指定缓存数量,同时搭配组件复用能力以达到性能最优效果。

如果您想系统深入地学习 HarmonyOS 开发或想考取HarmonyOS认证证书,欢迎加入华为开发者学堂:

请点击→: HarmonyOS官方认证培训

相关推荐
低调小一21 分钟前
深度复盘:KMP 在字节跳动的工程化落地实践
android·kotlin
编程乐学1 小时前
鸿蒙非原创--DevEcoStudio开发的奶茶点餐APP
华为·harmonyos·deveco studio·鸿蒙开发·奶茶点餐·鸿蒙大作业
鸣弦artha2 小时前
Flutter框架跨平台鸿蒙开发 —— Text Widget:文本展示的艺术
flutter·华为·harmonyos
lili-felicity3 小时前
React Native for Harmony:Rating 评分组件- 支持全星 / 半星 / 禁用 / 自定义样式
react native·华为·harmonyos
grd43 小时前
RN for OpenHarmony 小工具 App 实战:屏幕尺子实现
笔记·harmonyos
No Silver Bullet3 小时前
HarmonyOS NEXT开发进阶(十九):如何在 DevEco Studio 中查看已安装应用的运行日志
华为·harmonyos
歪楼小能手3 小时前
Android16系统go版关闭重力旋转开关后缺失手动旋转屏幕悬浮按钮
android·java·平板
崇山峻岭之间4 小时前
Matlab学习记录37
android·学习·matlab
大雷神5 小时前
HarmonyOS智慧农业管理应用开发教程--高高种地
华为·harmonyos
南村群童欺我老无力.6 小时前
Flutter 框架跨平台鸿蒙开发 - 开发双人对战五子棋游戏
flutter·游戏·华为·typescript·harmonyos