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官方认证培训

相关推荐
聚美智数7 小时前
智能结构化识别-图片结构解析-图像结构化解析-照片结构化解析
android·java·数据库
hqzing8 小时前
把 glibc 移植到鸿蒙 PC 上:它能用来做什么
华为·harmonyos
mmsx12 小时前
Android 插件化架构:40 个 Gradle 模块的拆分、通信与共存
android·kotlin
mmsx12 小时前
Android 不改一行源码:用 AspectJ 做三类拦截
android·kotlin
TST-魚爷12 小时前
易视讯会议摄像头 + 全向麦克风实操讲解稿
android·电脑·钉钉·腾讯会议·zoom会议
诸神缄默不语13 小时前
Zotero安装和简单使用教程
程序员
嘟哩DuliDuli13 小时前
AI创作工作区的项目上下文与多模态任务边界
android·人工智能·安全·ai·软件工程
OH_TPC13 小时前
HarmonyOS APP开发---“习惯猫“习惯打卡App,需要用到这个库
华为·harmonyos·鸿蒙
imDwAaY15 小时前
MySQL 存储引擎是什么?
android·数据库·mysql
TF男孩15 小时前
老AI人面对MCP、Skills等新名词
人工智能·程序员