作者:wanglei,华为UI编程结构技术专家

HarmonyOS自诞生以来,便是为满意分布式多设备运用场景而规划的,大到智慧屏、车机、平板,小到手机、手表。在多设备场景下进行运用UI界面开发,面临新的困难与应战,如下图所示:

1.jpg

​图1 多设备开发的应战

为了使UI界面在色彩风格、屏幕尺度、交互办法和组件功用等差异下仍能够正常显现,无疑需求开发人员花费大量精力在UI适配。开发人员常常需求完成多套界面布局(甚至多套工程),来满意不同设备间的规划差异。即使页面差异不大,也需求进行多设备测试,屡次打包编译在设备或许模仿器上运转检查作用。后期保护过程中也需求不断检查不同设备下的兼容性,这些都极大地添加了运用开发者的作业量。

为了解决上述问题,简化开发者在多设备上的开发调试本钱,咱们提出了一次开发多端布置的规划理念,完成经过一套工程代码,一次开发上架,即可按需布置到不同设备。为了完成这一方针,咱们从Harmony体系才能、ArkUI 3.0结构才能和开发工具才能三个方面,为开发者供给了多种适配办法和才能。下面将一一为咱们介绍。

一、HarmonyOS体系才能

首要介绍一下体系层面供给的才能。体系才能无需开发者进行页面调整,也无需进行事务逻辑调整,仅经过添加简略的几行装备描绘,即可由体系进行多设备适配。体系才能与开发范式无关,因而在新的UI编程结构下仍可运用。下面咱们顺次介绍两种体系才能:模仿小窗和平行视界。

1. 模仿小窗

模仿小窗是最常用也是最简略的一种多设备适配办法,经过运用体系的悬浮窗才能,将低分辨率的运用,以悬浮窗口的形式在高分辨率屏幕上进行显现。常见的运用场景是手机运用在平板或PC上运转的场景,如下图所示:

2.jpg

图2 模仿小窗

模仿小窗的运用办法非常简略,只需在项目中config.json文件中添加两条描绘,别离装备好运用的方针设备类型和呼应的窗口尺度,即可将低分辨率的运用运转在高分辨率设备上。示例代码如下:


{
  “app”: {
    ...
    “smartWindowSize”:“360*640”,
    “smartWindowDeviceType”: [
      “tablet”
    ]
  },
  ...
}仿制

这种运用办法能够杰出地确保咱们运用的展现作用和原始渠道作用是共同的,无需开发者进行额外的界面的适配。可是这种办法也有限制,最明显的问题便是没有办法运用悉数高分辨率的屏幕,整个屏幕内展现的数据量没有因屏幕分辨率的添加而增大,造成了屏幕上空间的糟蹋。为解决此问题,体系供给了另一种适配计划——平行视界。

2. 平行视界

体系针对折叠屏、平板设备供给了平行视界的才能,凭借分屏显现的思维,将屏幕分为左右两个部分,别离显现运用相关联的两个页面内容。这样每个区域都能够坚持杰出的界面显现作用,也添加了屏幕内的有效数据量,杰出地运用了屏幕显现区域。常用于新闻、购物类的场景,将相关的两个页面一同显现,如下图所示:

3.jpg

图3 平行视界

运用平行视界时,首要需求在config.json文件中装备metaData,声明支撑平行视界。一同,还需求添加easygo.json文件进行页面路由联系装备,辅导体系进行分屏显现。

平行视界的详细运用说明,可参考官网:

developer.harmonyos.com/cn/docs/doc…

二、ArkUI 3.0结构才能

上述两种是经过装备即可完成的多端适配计划,运用简略,可是运用场景比较受限。为了更加精准地适配多设备界面,ArkUI 3.0结构供给了媒体查询、多态控件、原子布局和栅格体系,便利开发者挑选适宜的才能进行UI界面构建。

1. 媒体查询

媒体查询是CSS供给的标准才能,是呼应式Web规划的要害部分。在新的UI范式中仍保存了此才能,作为最根底的UI呼应式规划才能。在新的UI范式中,经过API接口办法对外供给媒体查询才能,能够探查的规模包含页面尺度、设备分辨率、屏幕方向、页面宽高比、屏幕尺度、设备类型、屏幕类型和主题形式。开发者能够依据不同的查询成果,进行定制化处理。比方:当屏幕方向改变时,能够调整界面内布局款式和组件显现作用;也能够依据设备类型不同,操控组件的显现和躲藏;并且当查询状态发生改变时,供给事情告诉。

4.jpg

图4 媒体查询

2. 多态组件

UI界面构建离不开组件的运用。ArkUI 3.0结构为开发者供给了多态组件,经过组件将不同设备的款式风格和交互办法进行封装,替开发者完成大部分适配相关作业。开发者在运用多态组件时,无需考虑设备差异,只需重视功用完成即可。

下面经过一个示例来看看,相同的一套开发代码在手机、智慧屏和车机上展现的不同作用。

5.jpg

图5 多态组件

示例代码如下:


Column() {
    Text("手机 / 平板")
        .margin({top: 150})
    Button("普通按钮")
        .margin({top: 40})
        .onClick(() => {
            AlertDialog.show({title: '发现新版本', message: '当时运用移动数据网络,将消耗 XXX MB流量,是否更新',
            primaryButton: {
                value: '立即更新',
                action: () => {}
            },
            secondaryButton: {
                value: '今后再说',
                action: () => {}
            }})
        })
}仿制

产品规划人员常常不满意于运用体系默认款式,希望能够针对不同的渠道运用自定义的风格款式。为了避免开发者逐一组件地进行款式调整,ArkUI 3.0结构将组件款式相关设置信息(如色彩、尺度、圆角弧度、内容文本等)抽象出来形成了一个参数表,依照参数称号和参数值的办法进行映射。UI组件款式特点值都来自这张参数表,开发者和规划人员只需调整参数值,即可调整组件的显现作用。

3. 原子布局

多设备间差异最大的仍是屏幕的分辨率,差异分辨率适配离不开自适应布局的才能。针对常见的开发场景,咱们提炼了七种原子布局才能。这些布局能够独立运用,也可多种布局叠加运用。下面咱们顺次介绍这七种原子布局才能:

(1)折行布局: 常用于横竖屏适配或手机向平板切换的场景。比方,竖直方向空间减少,可是水平方向上显现区域添加,这时可考虑运用折行布局,将竖直方向的排版变成水平方向。

6.jpg

图6 折行布局

折行布局运用了Flex布局的折行才能完成,合作布局约束设置,即可完成折行排布作用。示例代码如下:


Flex({direction: FlexDirection.Column, wrap: FlexWrap.Wrap}) {
    Flex({justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center}) {
      Text("First Content")
      .fontColor(Color.White)
      .fontSize(30)
    }
    .constraintSize({minWidth: '50%', minHeight: '50%', maxWidth: 400})
    .backgroundColor(Color.Gray)
    Flex({justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center}) {
      Text("Second Content")
      .fontSize(30)
      .fontColor(Color.White)
    }
    .constraintSize({minWidth: '50%', minHeight: '50%', maxWidth: 400})
    .backgroundColor('rgb(207, 171, 103)')仿制

(2)均分布局: 常用于内容数量固定、均分显现的场景,比方工具栏、底部菜单栏等。

7.jpg

图7 均分布局

示例代码如下:


@Entry
@Component
struct Index {
    build() {
        Flex({direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.SpaceEvenly}) {
            Text('Hello')
                .fontSize(20)
                .borderColor(Color.Red)
                .borderWidth(1)
            Text('World')
                .fontSize(20)
                .borderColor(Color.Red)
                .borderWidth(1)
            Text('Ark')
                .fontSize(20)
                .borderColor(Color.Red)
                .borderWidth(1)
            Text('UI')
                .fontSize(20)
                .borderColor(Color.Red)
                .borderWidth(1)
        }
        .width('100%')
        .height('100%')
    }
}仿制

仅需装备为FlexAlign.SpaceEvenly形式,即可在Flex组件中将内容均分显现。

(3)躲藏布局: 是一种比较高级的布局办法,常用于分辨率改变较大,且不同分辨率下显现内容有所差异的场景。首要思维是经过添加或减少显现内容,来坚持最佳的显现作用。比方媒体播映操控器,在宽屏场景能够完好显现悉数操控项(包含播映、暂停、上一首、下一首、快进、快退,可能还有点赞和收藏按钮等),而在低分辨率场景只保存部分操控项(比方播映、暂停、上一首、下一首按钮)。

8.jpg

图8 躲藏布局

躲藏布局运用办法非常简略,只需经过displayPriority办法设置显现优先级,具有相同优先级的元素会一同显现或躲藏。在进行布局计算时,会依据当时可用空间,计算当时可显现组件进行显现。示例代码如下:


Row({space: 10}) {
  Text('1')
    .width(100)
    .textAlign(TextAlign.Center)
    .fontSize(40)
    .backgroundColor(Color.Red)
    .displayPriority(2)
  Text('2')
    .width(100)
    .fontSize(40)
    .textAlign(TextAlign.Center)
    .backgroundColor(Color.Red)
    .displayPriority(1)
  Text('3')
    .width(100)
    .textAlign(TextAlign.Center)
    .fontSize(40)
    .backgroundColor(Color.Red)
    .displayPriority(3)
  Text('4')
    .width(100)
    .textAlign(TextAlign.Center)
    .fontSize(40)
    .backgroundColor(Color.Red)
    .displayPriority(1)
  Text('5')
    .width(100)
    .textAlign(TextAlign.Center)
    .fontSize(40)
    .backgroundColor(Color.Red)
    .displayPriority(2)
}仿制

(4)占比布局: 是一种很常见的布局,便是依据容器尺度依照份额进行显现。

9.jpg

图9 占比布局

经过设置百分比尺度,即可完成份额调整。示例代码如下:


@Entry
@Component
struct Index {
    build() {
        Row() {
            Text('Hello')
                .fontSize(20)
                .width('50%')
                .backgroundColor(Color.Red)
            Text('World')
                .fontSize(20)
                .width('20%')
                .backgroundColor(Color.Yellow)
            Text('Ark')
                .fontSize(20)
                .width('15%')
                .backgroundColor(Color.Green)
            Text('UI')
                .fontSize(20)
                .width('15%')
                .backgroundColor(Color.Gray)
        }
        .width('100%')
        .height('100%')
    }
}仿制

(5)拉伸缩放布局: 组件尺度跟从父容器尺度改变,发生拉伸或缩放的展现作用。

10.jpg

图10 拉伸缩放布局

经过设置相对容器的份额,完成拉伸或缩放的展现作用。示例代码如下:


Row() {
        Image($r('app.media.background'))
          .objectFit(ImageFit.Fill)
          .width('100%')
          .height('100%')
    }仿制

(6)固定宽高比布局: 在拉伸缩放时坚持自身宽高比,一般用于图片缩放场景中,可坚持图片显现作用正常,避免图片被拉长或压瘪,引起显现失真。 

11.jpg

图11 固定宽高比布局

经过设置宽高比,坚持依照固定宽高比进行拉伸显现,保证图片不会发生变形。示例代码如下:


Row() {
    Image($r('app.media.background'))
      .objectFit(ImageFit.Fill)
      .width('100%')
      .height('100%')
      .aspectRatio(1.2)
}仿制

(7)延伸布局: 依据尺度调整内容显现数量,首要是经过像列表这样的才能来完成。

12.jpg

图12 延伸布局

依据宽度不同,显现不同数量的内容,并且能够经过滑动操作,显现出更多内容。示例代码如下:


@Entry
@Component
struct Index {
    private data: string[] = ['Hello', 'World', 'Ark', 'UI', 'This', 'Is', 'Layout', 'Demo']
    build() {
        Flex({direction:FlexDirection.Column, justifyContent: FlexAlign.Center}) {
          List({space: 10}) {
              ForEach(this.data, (item) => {
                  ListItem() {
                      Text(item)
                        .fontSize(20)
                        .width(80)
                  }.height(80)
                  .backgroundColor(Color.Red)
              })
          }
          .listDirection(Axis.Horizontal)
          .width('100%')
          .height(100)
        }
        .width('100%')
        .height('100%')
    }
}仿制

此示例经过List作为布局容器,进行内容线性排布,并支撑滑动呼应。

4. 栅格体系

ArkUI 3.0结构还供给了完好的栅格体系。所谓栅格体系是来自UX规划中的栅格规划,将屏幕宽度依照不同数量的栅格划分为不同的列,组件的尺度占用一个或多个栅格。选用这种办法进行规划的布局体系,称之为栅格体系。运用栅格体系,能够屏蔽屏幕分辨率的差异,在不同分辨率的屏幕上坚持显现内容的相对尺度共同。

常见的栅格体系有8栅格体系和12栅格体系,而咱们供给的是动态栅格体系,能够依据不同的屏幕尺度,动态地调整栅格数量。运用动态栅格体系时,不同分辨率的设备运用不同的栅格装备,比方:手机竖屏选用4栅格体系,手机横屏和折叠屏选用8栅格体系,大屏选用12栅格体系。

13.jpg

图13 动态栅格体系

为了便利开发者运用,ArkUI 3.0结构供给了栅格布局容器GridContainer。下面咱们来看一个示例,代码如下:


Stack() {
  GridContainer({sizeType: SizeType.Auto}) {
    Row() {
      Button('OK')
        .fontSize(30)
        .gridSpan(2)
        .useSizeType({lg: 4})
    }
  }
}仿制

栅格布局容器能够设置为固定栅格数,也能够设置为Auto形式。此示例选用的是Auto形式,栅格布局容器会依据宽度动态调整栅格数量。一同经过useSizeType特点办法,能够设置在不同栅格形式下,组件占用的栅格数量。比方:“.useSizeType({lg: 4})”表明在large栅格体系(即12栅格体系)中,Button组件宽度占用4栅格显现。

因而,此示例在手机和平板上的显现作用如下:

14.jpg

图14 显现作用

三、开发工具才能

除了上面的体系才能和ArkUI 3.0结构才能外,咱们还从开发工具(DevEco Studio)方面,为开发者供给了各种各样的开发模板,以及多设备预览等才能,减少开发者的开发调试本钱,提升开发功率。

1. 开发模板

开发模板首要包含工程模板和卡片模板。

  • 工程模板: DevEco Studio预置了丰厚的工程模板,能够依据工程导游轻松创建适应于各类设备的工程,并自动生成对应的代码和资源模板。创建工程时,开发者能够挑选适宜的工程模板。
  • 卡片模板: DevEco Studio供给了多种类型的卡片模板,开发者能够依据需求展现的信息类型灵敏挑选模板,快速构建服务卡片。

15.png

图15 工程模板和卡片模板

2. 多设备预览

DevEco Studio还支撑多设备预览才能,开发者能够在同一窗口中,一同检查多种设备下UI界面的展现作用。预览器与真机设备选用相同渲染引擎和UI结构,能够最大程度地做到预览作用与真机运转作用的共同。以下视频展现了多设备预览才能:

视频 gif.gif

感兴趣的小伙伴,能够从官网下载和体会DevEco Studio新版本:developer.harmonyos.com/cn/develop/…

四、结束语

完成完美的一次开发多端布置作用,离不开开发者的参与。UI开发结构和体系在完成一次开发多端布置的过程中进行了初步的探索,也等待开发者能反馈更多的多设备UI开发过程中的痛点,以及等待体系结构供给的才能。欢迎开发者和咱们一同,在开源社区将一次开发多端布置的才能丰厚起来!

 

 cke_542.gif​​​

扫码添加开发者小帮手微信

获取更多HarmonyOS开发资源和开发者活动资讯