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

相关推荐
千里马学框架3 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台3 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone3 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
youyin3 天前
HarmonyOS ArkUI 组件与自定义组件零基础:从搭页面到组件化开发
华为·harmonyos
致远ccc3 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo3 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077003 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼3 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
HwJack203 天前
【HarmonyOS开发小实践】ArkTS 从 TypeScript 到方舟语言的演进
华为·harmonyos
duyacode3 天前
FastAPI为什么成为默认答案
程序员