共计 7008 个字符,预计需要花费 18 分钟才能阅读完成。
作者:wanglei,华为 UI 编程框架技术专家
HarmonyOS 自诞生以来,就是为满足分布式多设施利用场景而设计的,大到智慧屏、车机、平板,小到手机、手表。在多设施场景下进行利用 UI 界面开发,面临新的艰难与挑战,如下图所示:
图 1 多设施开发的挑战
为了使 UI 界面在色调格调、屏幕尺寸、交互方式和组件性能等差别下仍可能失常显示,无疑须要开发人员破费大量精力在 UI 适配。开发人员经常须要实现多套界面布局(甚至多套工程),来满足不同设施间的设计差别。即便页面差别不大,也须要进行多设施测试,屡次打包编译在设施或者模拟器上运行查看成果。前期保护过程中也须要一直查看不同设施下的兼容性,这些都极大地减少了利用开发者的工作量。
为了解决上述问题,简化开发者在多设施上的开发调试老本,咱们提出了一次开发多端部署的设计理念,实现通过一套工程代码,一次开发上架,即可按需部署到不同设施。为了实现这一指标,咱们从 Harmony 零碎能力、ArkUI 3.0 框架能力和开发工具能力三个方面,为开发者提供了多种适配办法和能力。上面将一一为大家介绍。
一、HarmonyOS 零碎能力
首先介绍一下零碎层面提供的能力。零碎能力无需开发者进行页面调整,也无需进行业务逻辑调整,仅通过减少简略的几行配置形容,即可由零碎进行多设施适配。零碎能力与开发范式无关,因而在新的 UI 编程框架下仍可应用。上面咱们顺次介绍两种零碎能力:模仿小窗和平行视界。
- 模仿小窗
模仿小窗是最罕用也是最简略的一种多设施适配形式,通过利用零碎的悬浮窗能力,将低分辨率的利用,以悬浮窗口的模式在高分辨率屏幕上进行显示。常见的应用场景是手机利用在平板或 PC 上运行的场景,如下图所示:
图 2 模仿小窗
模仿小窗的应用形式非常简单,只需在我的项目中 config.json 文件中减少两条形容,别离配置好利用的指标设施类型和响应的窗口尺寸,即可将低分辨率的利用运行在高分辨率设施上。示例代码如下:
{
“app”: {
...“smartWindowSize”:“360*640”,“smartWindowDeviceType”: [“tablet”]
},
…
}
复制
这种应用形式可能良好地保障咱们利用的展现成果和原始平台成果是统一的,无需开发者进行额定的界面的适配。然而这种形式也有局限,最显著的问题就是没有方法利用全副高分辨率的屏幕,整个屏幕内展现的数据量没有因屏幕分辨率的减少而增大,造成了屏幕上空间的节约。为解决此问题,零碎提供了另一种适配计划——平行视界。
- 平行视界
零碎针对折叠屏、平板设施提供了平行视界的能力,借助分屏显示的思维,将屏幕分为左右两个局部,别离显示利用相关联的两个页面内容。这样每个区域都可能保持良好的界面显示成果,也减少了屏幕内的无效数据量,良好地利用了屏幕显示区域。罕用于新闻、购物类的场景,将相干的两个页面同时显示,如下图所示:
图 3 平行视界
应用平行视界时,首先须要在 config.json 文件中配置 metaData,申明反对平行视界。同时,还须要减少 easygo.json 文件进行页面路由关系配置,领导零碎进行分屏显示。
平行视界的具体应用阐明,可参考官网:
https://developer.harmonyos.c…
二、ArkUI 3.0 框架能力
上述两种是通过配置即可实现的多端适配计划,应用简略,然而应用场景比拟受限。为了更加精准地适配多设施界面,ArkUI 3.0 框架提供了媒体查问、多态控件、原子布局和栅格零碎,不便开发者抉择适合的能力进行 UI 界面构建。
- 媒体查问
媒体查问是 CSS 提供的规范能力,是响应式 Web 设计的要害局部。在新的 UI 范式中仍保留了此能力,作为最根底的 UI 响应式设计能力。在新的 UI 范式中,通过 API 接口方式对外提供媒体查问能力,能够探查的范畴包含页面尺寸、设施分辨率、屏幕方向、页面宽高比、屏幕尺寸、设施类型、屏幕类型和主题模式。开发者能够依据不同的查问后果,进行定制化解决。比方:当屏幕方向变动时,能够调整界面内布局款式和组件显示成果;也能够依据设施类型不同,管制组件的显示和暗藏;并且当查问状态发生变化时,提供事件告诉。
图 4 媒体查问
- 多态组件
UI 界面构建离不开组件的应用。ArkUI 3.0 框架为开发者提供了多态组件,通过组件将不同设施的款式格调和交互方式进行封装,替开发者实现大部分适配相干工作。开发者在应用多态组件时,无需思考设施差别,只需关注性能实现即可。
上面通过一个示例来看看,雷同的一套开发代码在手机、智慧屏和车机上展现的不同成果。
图 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 组件款式属性值都来自这张参数表,开发者和设计人员只需调整参数值,即可调整组件的显示成果。
- 原子布局
多设施间差别最大的还是屏幕的分辨率,差别分辨率适配离不开自适应布局的能力。针对常见的开发场景,咱们提炼了七种原子布局能力。这些布局能够独立应用,也可多种布局叠加应用。上面咱们顺次介绍这七种原子布局能力:
(1)折行布局:罕用于横竖屏适配或手机向平板切换的场景。比方,竖直方向空间缩小,然而程度方向上显示区域减少,这时可思考应用折行布局,将竖直方向的排版变成程度方向。
图 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 均分布局
示例代码如下:
@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 暗藏布局
暗藏布局应用形式非常简单,只需通过 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 占比布局
通过设置百分比尺寸,即可实现比例调整。示例代码如下:
@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 拉伸缩放布局
通过设置绝对容器的比例,实现拉伸或缩放的展现成果。示例代码如下:
Row() {
Image($r('app.media.background'))
.objectFit(ImageFit.Fill)
.width('100%')
.height('100%')
}
复制
(6)固定宽高比布局:在拉伸缩放时放弃本身宽高比,通常用于图片缩放场景中,可放弃图片显示成果失常,防止图片被拉长或压瘪,引起显示失真。
图 11 固定宽高比布局
通过设置宽高比,放弃依照固定宽高比进行拉伸显示,保障图片不会产生变形。示例代码如下:
Row() {
Image($r('app.media.background'))
.objectFit(ImageFit.Fill)
.width('100%')
.height('100%')
.aspectRatio(1.2)
}
复制
(7)延长布局:依据尺寸调整内容显示数量,次要是通过像列表这样的能力来实现。
图 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 作为布局容器,进行内容线性排布,并反对滑动响应。
- 栅格零碎
ArkUI 3.0 框架还提供了残缺的栅格零碎。所谓栅格零碎是来自 UX 设计中的栅格设计,将屏幕宽度依照不同数量的栅格划分为不同的列,组件的尺寸占用一个或多个栅格。采纳这种形式进行设计的布局零碎,称之为栅格零碎。应用栅格零碎,能够屏蔽屏幕分辨率的差别,在不同分辨率的屏幕上放弃显示内容的绝对尺寸统一。
常见的栅格零碎有 8 栅格零碎和 12 栅格零碎,而咱们提供的是动静栅格零碎,能够依据不同的屏幕尺寸,动静地调整栅格数量。应用动静栅格零碎时,不同分辨率的设施应用不同的栅格配置,比方:手机竖屏采纳 4 栅格零碎,手机横屏和折叠屏采纳 8 栅格零碎,大屏采纳 12 栅格零碎。
图 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 显示成果
三、开发工具能力
除了下面的零碎能力和 ArkUI 3.0 框架能力外,咱们还从开发工具(DevEco Studio)方面,为开发者提供了各种各样的开发模板,以及多设施预览等能力,缩小开发者的开发调试老本,晋升开发效率。
- 开发模板
开发模板次要包含工程模板和卡片模板。
工程模板:DevEco Studio 预置了丰盛的工程模板,能够依据工程向导轻松创立适应于各类设施的工程,并主动生成对应的代码和资源模板。创立工程时,开发者能够筛选适合的工程模板。
卡片模板:DevEco Studio 提供了多种类型的卡片模板,开发者能够依据须要展现的信息类型灵便抉择模板,疾速构建服务卡片。
图 15 工程模板和卡片模板
- 多设施预览
DevEco Studio 还反对多设施预览能力,开发者能够在同一窗口中,同时查看多种设施下 UI 界面的展现成果。预览器与真机设备采纳雷同渲染引擎和 UI 框架,能够最大水平地做到预览成果与真机运行成果的统一。以下视频展现了多设施预览能力:
Play Video
感兴趣的小伙伴,能够从官网下载和体验 DevEco Studio 新版本:https://developer.harmonyos.c…
四、结束语
实现完满的一次开发多端部署成果,离不开开发者的参加。UI 开发框架和零碎在实现一次开发多端部署的过程中进行了初步的摸索,也期待开发者能反馈更多的多设施 UI 开发过程中的痛点,以及期待零碎框架提供的能力。欢送开发者和咱们一起,在开源社区将一次开发多端部署的能力丰盛起来!