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

相关推荐
uzong10 小时前
技术人职场个人影响力打造:技巧、路径与实战总结
程序员
符哥200810 小时前
充电桩 WiFi 局域网配网(Android/Kotlin)流程、指令及实例说明文档
android·开发语言·kotlin
uzong11 小时前
技术管理者,什么是 high level 的事情
程序员
没有了遇见11 小时前
Android 项目架构之<用户信息模块>
android
Georgewu12 小时前
如何判断应用在鸿蒙卓易通或者出境易环境下?
android·harmonyos
localbob13 小时前
Pico 4XVR 1.10.13安装包下载与安装教程 ico 4XVR最新版下载、4XVR 1.10.13 APK安装包、Pico VR看电影软件、4XVR完整版安装教程、Pico 4播放器推荐、V
android·vr·vr播放器·vr眼镜播放器下载·pico 4xvr·4xvr下载·pico 4xvr最新版安装包
菜鸟不学编程13 小时前
鸿蒙中的 AR/VR 开发与场景创建
ar·vr·harmonyos
峥嵘life13 小时前
Android16 EDLA【CTS】CtsConnectivityMultiDevicesTestCases存在fail项
android·学习
大傻^13 小时前
SpringAI2.0 Null Safety 实战:JSpecify 注解体系与 Kotlin 互操作
android·开发语言·人工智能·kotlin·springai
游戏开发爱好者813 小时前
React Native iOS 代码如何加密,JS 打包 和 IPA 混淆
android·javascript·react native·ios·小程序·uni-app·iphone