鸿蒙5.0实战开发之一多分栏开发实践

往期推文全新看点(文中附带全新鸿蒙5.0全栈学习笔录)

✏️ 鸿蒙应用开发与鸿蒙系统开发哪个更有前景?

✏️ 嵌入式开发适不适合做鸿蒙南向开发?看完这篇你就了解了~

✏️ 对于大前端开发来说,转鸿蒙开发究竟是福还是祸?

✏️ 鸿蒙岗位需求突增!移动端、PC端、IoT到底该怎么选?

✏️ 记录一场鸿蒙开发岗位面试经历~

✏️ 持续更新中……


概述

目前智能终端设备的种类繁多,不同类型的设备屏幕大小、用户使用习惯也存在不同,这给UI布局以及功能适配带来了很多挑战。以分栏布局为例,在手机、折叠屏以及平板下,最佳显示效果存在如下差异:

  • 手机仅支持单栏显示
  • 折叠屏可以支持单双栏显示
  • 平板支持三栏显示

本文提供了一种“通过判断屏幕尺寸,选择合适的分栏布局”的方法,解决HarmonyOS的1+8多种形态设备的UI适配问题。通过该方法,开发者无需关注设备类型,即可达到多设备的自适应分栏布局效果,实现“一次开发,多端部署”。

开发者可以根据屏幕尺寸断点,灵活使用Navigation组件和SidebarContainer组件来实现不同的分栏效果。

分栏实现原理

单双栏

单双栏通常是使用Navigation实现的,Navigation是路由容器组件,一般作为首页的根容器,包括单栏(Stack)、分栏(Split)和自适应(Auto)三种显示模式。自适应模式下,当页面宽度大于等于一定阈值时,Navigation组件采用分栏模式,反之采用单栏模式。

开发者可以通过更改Navigation组件的mode值来实现单双栏的切换,如果断点为sm,则mode值为Stack。如果不为sm,则mode值为Split,即可实现单双栏的自适应切换。

Navigation(this.pathInfo) {
  // ...
}
.mode(this.currentBreakPoint === 'sm' ? NavigationMode.Stack : this.notesNavMode)

三分栏

Navigation组件实现了单双栏的效果。那么,在更大的屏幕宽度,要实现三分栏效果该如何实现呢?三分栏可以组合使用 SideBarContainer 与 Navigation组件 实现。SideBarContainer提供侧边栏可以显示和隐藏的侧边栏容器,通过子组件定义侧边栏和内容区,第一个子组件表示侧边栏,第二个子组件表示内容区。我们可以在内容区中加入Navigation组件,即可实现三分栏效果。

我们可以通过更改SideBarContainer组件的showSideBar值来控制是否显示侧边栏。如果断点为lg,则showSideBar值为true,默认显示侧边栏,反之,则为false,不显示。

SideBarContainer(SideBarContainerType.AUTO) {
  // 导航栏
  Column() {
    MailSideBar()
  }
  .width('100%')
  .height('100%')
  .backgroundColor('#f1f3f5')

  // 内容区
  Column() {
    Stack() {
      MailNavigation()
      // ...
    }
  }
  .height('100%')
  .width('100%')
}
.showSideBar(this.currentBreakPoint === 'lg')

场景案例

典型场景

应用页面有层级关系,例如一级目录、二级目录、内容区,典型的场景比如日常使用的邮箱功能。

邮箱是分为三个层级目录,第一层级为账户信息,第二层级为邮件列表(一个账户信息对应多条邮件信息),第三层级为邮件详情,是一个很典型的三分栏场景。根据内容的重要性,开发者通常在单栏显示邮件详情,双栏显示邮件列表、邮件详情,三栏显示账户、邮件列表、内容区。

对于邮箱页面的一多分栏变化,开发者可以抽象为

示例代码

  • 对SideBarContainer组件的showSideBar属性进行赋值,如果断点为lg,则默认显示侧边栏,反之,则默认不显示。
// entry/src/main/ets/application/MailBox.ets
build() {
  // ...
      SideBarContainer(SideBarContainerType.AUTO) {
        // 导航栏
        Column() {
          MailSideBar()
        }
        .width('100%')
        .height('100%')
        .backgroundColor('#f1f3f5')

        // 内容区
        Column() {
          Stack() {
            MailNavigation()
            // ...
          }
        }
        .height('100%')
        .width('100%')
      }
      .showSideBar(this.currentBreakPoint === 'lg')
      // ...
}
  • 在SideBarContainer组件内容区中使用Navigation组件,对Navigation组件的mode属性进行赋值,如果断点为sm,则为单栏,反之则为双栏。
// entry/src/main/ets/common/MailNavigation.ets
build() {
  Navigation(this.pathInfo) {
    // ...
  }
  .mode(this.currentBreakPoint === 'sm' ? NavigationMode.Stack : this.notesNavMode)
  .navDestination(this.myRouter)
  // ...
}

其他场景

大部分情况下,单栏展示的是Navigation的内容区,但是存在某些场景,内容区的优先级比导航区的优先级要低,比如日历日程功能,在单栏的情况下,展示的是日历(Navigation的导航区)。效果如下。

日历日程分为三个层级,账户消息->日历->日程,开发者通常在单栏显示日历,双栏显示日历、日程,三栏显示账户信息、日历、日程。日历日程页面与邮箱页面的主要区别为,日历日程页面的单栏页面显示Navigation导航栏。

示例代码

在Navigation的onNavigationModeChange属性中进行判断,当Navigation首次显示或者单双栏状态发生变化时。

  • 如果是单栏,则清空PathInfo路由,则Navigation的内容区不显示,即可实现单屏显示Navigation导航栏的目的。
  • 如果为双栏,则重新向PathInfo路由中push内容区参数,即可达到单栏变双栏的目的。
Navigation(this.calendarPageInfos) {
  CalendarView()
}
.navDestination(this.pageMap)
.mode(this.breakPoint === CommonConstants.BREAK_POINT_SM ? NavigationMode.Stack : this.navMode)
// ...
.onNavigationModeChange((mode: NavigationMode) => {
  if (this.breakPoint === CommonConstants.BREAK_POINT_SM || mode === NavigationMode.Stack) {
    this.calendarPageInfos.clear();
  } else if (mode === NavigationMode.Split) {
    this.calendarPageInfos.pushPath({ name: this.selectedItem.date, param: this.selectedItem }, false);
  }
})

还有一种SideBarContainer在页面右边的场景,比如大多数页面的智能客服场景。通过sidebarposition属性设置侧边栏右侧显示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值