鸿蒙PC应用开发——挪移布局与缩进布局
挪移布局是指在空间充足时,通过调整组件的位置与展示方式,在左右布局与上下布局之间切换,用以展示更多内容或提高用户体验。常用的挪移布局包括插图和文字组合布局、底部/侧边导航。
【高心星出品】
鸿蒙PC应用开发——挪移布局与缩进布局
| 插图和文字组合布局 | GridRow/GridCol组件+断点+栅格 |
|---|---|
| 底部/侧边导航 | SideBarContainer组件+断点 |
| 单列列表布局 | GridRow/GridCol组件+断点+栅格 |
挪移布局
挪移布局是指在空间充足时,通过调整组件的位置与展示方式,在左右布局与上下布局之间切换,用以展示更多内容或提高用户体验。常用的挪移布局包括插图和文字组合布局、底部/侧边导航。
插图和文字组合布局
插图和文字组合布局基于横向断点,设置组件所占不同的栅格数,实现左右布局与上下布局的切换。
布局效果

实现方案
设置不同横向断点下,GridRow组件的columns、breakpoints属性,和GridCol组件的span属性实现目标效果。
示例代码
GridRow({
columns: { xs: 4, sm: 4, md: 8, lg: 12, xl: 12 },
gutter: 0,
breakpoints: { value: ['320vp', '600vp', '840vp', '1440vp']},
direction: GridRowDirection.Row
}) {
GridCol({
span: { xs: 4, sm: 4, md: 4, lg: 4, xl: 4 },
offset: 0
}) {
// ...
}
.height(this.mainWindowInfo.widthBp === WidthBreakpoint.WIDTH_SM ? this.getGridColHeight() : '100%')
.padding({ top: this.getUIContext().px2vp(this.mainWindowInfo.AvoidSystem?.topRect.height) + 12})
.backgroundColor('#AAD3F1')
GridCol({
span: { xs: 4, sm: 4, md: 4, lg: 8, xl: 8 },
offset: 0
}) {
// ...
}
.backgroundColor(Color.Pink)
.layoutWeight(1)
.padding({ top: this.mainWindowInfo.widthBp === WidthBreakpoint.WIDTH_SM ? 0 :
this.getUIContext().px2vp(this.mainWindowInfo.AvoidSystem?.topRect.height) })
}
代码逻辑走读:
- 初始化网格布局:
- 使用
GridRow组件初始化一个网格行,设置了列的数量、间距和断点,方向为行方向。
- 使用
- 定义第一个网格列:
- 使用
GridCol定义一个网格列,设置列在不同屏幕尺寸下的跨度和偏移量。 - 设置列的高度和内边距,根据屏幕宽度调整高度和内边距的值。
- 设置背景颜色为
#AAD3F1。
- 使用
- 定义第二个网格列:
- 使用
GridCol定义另一个网格列,设置列在不同屏幕尺寸下的跨度和偏移量。 - 设置背景颜色为粉色。
- 设置布局权重为1,根据屏幕宽度调整内边距的值。
- 使用
- 布局适应性:
- 通过
breakpoints和span的设置,确保布局在不同屏幕尺寸下都能自适应显示。 - 使用
layoutWeight来控制列的布局权重,影响在多余空间的分配。
- 通过
此布局场景也常用于页面顶部页签与搜索框,具体可参考如下布局效果。

底部/侧边导航
底部/侧边导航基于横向断点,设置导航栏的位置与方向,实现上下布局与左右布局的切换。
电脑设备上的商务办公、实用工具垂类应用开发中,常使用侧边分级导航展示多级目录。而在一多开发时,侧边分级导航并不一定适用于手机、平板等设备,若需要实现导航栏内的分级效果,比较复杂。
当前系统支持手机、折叠屏、平板和电脑四种产品形态,分别对应sm、md、lg和xl四个断点,下文将实现不同断点下的分级导航栏。
布局效果

当断点为sm或md时,显示底部导航和顶部页签;当断点为lg时,显示左侧导航;当断点为xl或设备为PC/2in1时,侧边显示一级和二级导航。
实现方案
开发一多分级导航栏时,需要实现4种断点下的一多效果:
- 订阅窗口尺寸变化,更新断点,触发页面布局更新。
- 在sm和md断点下,分级导航由底部一级导航栏和顶部二级页签组成。
- 在lg断点下,分级导航由侧边一级导航栏和顶部二级页签组成。
- 使用电脑设备或xl断点下,通过侧边栏显示一级和二级导航。
设置不同横向断点下,Tabs组件的barPosition、vertical、barHeight、barWidth和barMode属性实现目标效果。
示例代码
在sm、md和lg断点下,在首页调用Tabs组件,渲染一级导航目录信息到页签,并在内容区域调用已实现的页面视图,实现页面效果
// entry/src/main/ets/view/TabsView/TabsView.ets
Tabs({
barPosition: this.mainWindowInfo.widthBp === WidthBreakpoint.WIDTH_LG ? BarPosition.Start : BarPosition.End
}) {
TabContent() {
TopTabView({
pageInfos: this.pageInfos,
mainWindowInfo: this.mainWindowInfo,
firstLevelIndex: this.firstLevelIndex,
tabData: this.tabData
})
}
.tabBar(this.tabBuilder(this.firstTabList[0], 0))
TabContent()
.tabBar(this.tabBuilder(this.firstTabList[1], 1))
TabContent()
.tabBar(this.tabBuilder(this.firstTabList[2], 2))
TabContent()
.tabBar(this.tabBuilder(this.firstTabList[3], 3))
}
.barBackgroundColor('#CCF1F3F5')
.barWidth(this.mainWindowInfo.widthBp === WidthBreakpoint.WIDTH_LG ? 96 : '100%')
.barHeight(this.mainWindowInfo.widthBp === WidthBreakpoint.WIDTH_LG ? '100%' : 56 + this.getUIContext().px2vp(this.mainWindowInfo.AvoidNavigationIndicator?.bottomRect.height))
.barMode(this.mainWindowInfo.widthBp === WidthBreakpoint.WIDTH_LG ? BarMode.Scrollable : BarMode.Fixed,
{ nonScrollableLayoutStyle: LayoutStyle.ALWAYS_CENTER })
.barBackgroundBlurStyle(BlurStyle.COMPONENT_THICK)
.vertical(this.mainWindowInfo.widthBp === WidthBreakpoint.WIDTH_LG)
.onChange((index: number) => {
this.firstLevelIndex = index;
})
- Tabs组件初始化:
- 创建一个Tabs组件,选项卡栏的位置基于
mainWindowInfo.widthBp的值。如果是宽窗口(WIDTH_LG),则选项卡栏在顶部(BarPosition.Start),否则在底部(BarPosition.End)。
- 创建一个Tabs组件,选项卡栏的位置基于
- TabContent定义:
- 定义了四个TabContent组件,每个组件都有一个自定义的标签栏。标签栏的构建使用
tabBuilder方法,传入不同的参数来生成不同的标签。
- 定义了四个TabContent组件,每个组件都有一个自定义的标签栏。标签栏的构建使用
- 标签栏样式设置:
- 设置选项卡栏的背景颜色、宽度、高度、模式和背景模糊样式。这些样式根据窗口宽度断点动态调整。
- 选项卡切换事件处理:
- 当选项卡切换时,更新
firstLevelIndex的值,以反映当前选中的选项卡索引。
- 当选项卡切换时,更新
- 布局方向设置:
- 根据窗口宽度断点,设置布局的方向是垂直还是水平。
在xl断点下或使用PC/2in1设备,首页调用SideBarContainer组件,传入侧边栏区域组件和内容区域组件。此时可以结合@State和@Link装饰器,同步所需要的参数信息,如当前选中的一级目录索引和二级目录索引,可以用于呈现与页签强相关的页面内容。
// entry/src/main/ets/view/TabsView/TabsView.ets
if ((this.mainWindowInfo.widthBp === WidthBreakpoint.WIDTH_LG || this.mainWindowInfo.widthBp
=== WidthBreakpoint.WIDTH_XL)&& deviceInfo.deviceType == "2in1") {
// Use SideBarContainer at XL breakpoint.
SideBarContainer(SideBarContainerType.Embed) {
TabSideBarView({
firstLevelIndex: this.firstLevelIndex,
secondLevelIndex: this.secondLevelIndex,
tabData: this.tabData,
firstTabList: this.firstTabList
})
Column() {
Row() {
// ...
Text(this.tabViewModel.getTabNameOfSecondLevel(this.tabViewModel.getTabNameOfFirstLevel(this.firstLevelIndex),
this.secondLevelIndex))
.fontSize('20fp')
.fontWeight(700)
.margin({
left: 16,
})
}
.padding({
top: 60,
bottom: 14,
})
VideoInfoView({
mainWindowInfo: this.mainWindowInfo,
firstLevelIndex: this.firstLevelIndex,
secondLevelIndex: this.secondLevelIndex
})
}
.alignItems(HorizontalAlign.Start)
}
.autoHide(false)
.divider({ strokeWidth: 0.3 })
.showControlButton(false)
.sideBarWidth(240)
.minSideBarWidth(240)
.maxSideBarWidth(240)
} else {
// ...
}
- 条件判断:代码首先检查当前设备的屏幕宽度是否为较大的断点(
WIDTH_LG或WIDTH_XL),并且设备类型是否为“2in1”。- 如果条件满足,则进入侧边栏布局的逻辑。
- 如果条件不满足,则可能进入其他布局逻辑(代码中未完全展示)。
- 侧边栏容器:当条件满足时,创建一个
SideBarContainer,类型为Embed。- 在这个容器中,首先实例化
TabSideBarView,传入相关的参数。
- 在这个容器中,首先实例化
- 内容布局:在
SideBarContainer内部,使用Column和Row组件来组织布局。Row中包含一个Text组件,用于显示标签名称,设置了字体大小、字体粗细和左边距。Column中包含两个子组件:Row和VideoInfoView,分别用于显示文本信息和视频信息。
- 样式和属性设置:为
Row和Column设置了一些样式和属性,如填充、对齐方式、边距等。 - 侧边栏属性:为
SideBarContainer设置了一些属性,如是否自动隐藏、分隔线宽度、控制按钮显示状态、侧边栏宽度等。
缩进布局
缩进布局是指在空间充足时,组件居中展示并在两侧留白,通过调整内容的缩进来建立视觉层次结构,提高可读性和美观性。常用的缩进布局包括单列列表布局。
单列列表布局
单列列表布局基于横向断点,设置栅格子组件所占的栅格列数和偏移列数,实现缩进布局。
布局效果

实现方案
设置不同横向断点下,GridRow组件的columns、breakpoints属性和GridCol组件的span、offset属性实现目标效果。
示例代码
GridRow({
columns: { xs: 4, sm: 4, md: 8, lg: 12, xl: 12 },
gutter: 0,
breakpoints: { value: ['320vp', '600vp', '840vp', '1440vp']},
direction: GridRowDirection.Row
}) {
GridCol({
span: { xs: 4, sm: 4, md: 6, lg: 8, xl: 8 },
offset: { xs: 0, sm: 0, md: 1, lg: 2, xl: 2 }
}) {
// ...
}
.width('100%')
.height('100%')
}
- GridRow组件定义:
- 创建了一个GridRow组件,设置了列数(columns)和间距(gutter)。
- columns属性定义了不同屏幕尺寸下的列数,如xs、sm、md、lg、xl分别对应320vp、600vp、840vp、1440vp的设备。
- gutter属性设置为0,表示列之间的间距为0。
- breakpoints属性定义了不同屏幕尺寸下的断点,用于调整布局。
- direction属性设置为GridRowDirection.Row,表示布局方向为行。
- GridCol组件定义:
- 在GridRow中定义了一个GridCol组件,设置了列的跨度(span)和偏移(offset)。
- span属性定义了不同屏幕尺寸下的列跨度,如xs、sm、md、lg、xl分别对应320vp、600vp、840vp、1440vp的设备。
- offset属性定义了不同屏幕尺寸下的列偏移,如xs、sm、md、lg、xl分别对应320vp、600vp、840vp、1440vp的设备。
- 样式设置:
- 对GridCol组件设置了宽度(.width(‘100%’))和高度(.height(‘100%’)),使其在不同设备上占据整个父容器的空间。
更多推荐

所有评论(0)