
项目已开源,开源地址: https://gitcode.com/nutpi/HarmonyosNextCaseStudyTutorial , 欢迎fork & star

底部导航栏是移动应用中最常见的导航元素之一,它通常包含多个均匀分布的图标或按钮,用于在应用的主要功能之间切换。在HarmonyOS NEXT中,RelativeContainer组件提供了强大的链式布局(Chain)功能,能够轻松实现元素的均匀分布,非常适合底部导航栏的实现。本教程将详细讲解如何利用RelativeContainer的水平链布局功能实现一个美观、均匀分布的底部导航栏。
链式布局是RelativeContainer提供的一种特殊的布局方式,它可以将一组组件按照特定的方式排列在一条直线上,并控制它们之间的间距和分布方式。链式布局可以是水平的或垂直的,并支持多种分布模式。
@Component
export struct BottomNav {
build() {
RelativeContainer() {
// 首页图标
Image($r('app.media.home'))
.width(24)
.height(24)
.id("home")
.alignRules({
left: { anchor: "parent", align: HorizontalAlign.Start },
bottom: { anchor: "parent", align: VerticalAlign.Bottom }
})
// 消息图标
Image($r('app.media.message'))
.width(24)
.height(24)
.id("message")
.alignRules({
left: { anchor: "parent", align: HorizontalAlign.Center },
bottom: { anchor: "parent", align: VerticalAlign.Bottom }
})
// 我的图标
Image($r('app.media.profile'))
.width(24)
.height(24)
.id("profile")
.alignRules({
left: { anchor: "parent", align: HorizontalAlign.End },
bottom: { anchor: "parent", align: VerticalAlign.Bottom }
})
}
.chainMode([
{
id: "horizontalChain",
direction: Direction.HORIZONTAL,
style: ChainStyle.SPREAD,
components: ["home", "message", "profile"]
}
])
.width('100%')
.height(56)
.backgroundColor('#ffffff')
}
}RelativeContainer() {
// 子组件
}
.chainMode([
{
id: "horizontalChain",
direction: Direction.HORIZONTAL,
style: ChainStyle.SPREAD,
components: ["home", "message", "profile"]
}
])
.width('100%')
.height(56)
.backgroundColor('#ffffff')这部分代码创建了一个RelativeContainer容器,并设置了以下属性:
属性 | 值 | 说明 |
|---|---|---|
chainMode | […] | 定义链式布局数组 |
width | ‘100%’ | 容器宽度为父容器的100% |
height | 56 | 容器高度为56vp |
backgroundColor | ‘#ffffff’ | 背景色为白色 |
这里的关键是chainMode属性,它定义了一个水平链:
这个水平链将三个图标组件连接起来,并使它们在容器中均匀分布。
Image($r('app.media.home'))
.width(24)
.height(24)
.id("home")
.alignRules({
left: { anchor: "parent", align: HorizontalAlign.Start },
bottom: { anchor: "parent", align: VerticalAlign.Bottom }
})首页图标的关键属性设置:
属性 | 值 | 说明 |
|---|---|---|
width | 24 | 宽度为24vp |
height | 24 | 高度为24vp |
id | “home” | 组件的唯一标识符,用于链式布局引用 |
alignRules.left | { anchor: “parent”, align: HorizontalAlign.Start } | 左侧对齐父容器的左侧 |
alignRules.bottom | { anchor: “parent”, align: VerticalAlign.Bottom } | 底部对齐父容器的底部 |
这里的关键点是为首页图标设置了一个唯一的ID “home”,这样链式布局就可以引用它。同时,图标被定位在容器的左下角。
Image($r('app.media.message'))
.width(24)
.height(24)
.id("message")
.alignRules({
left: { anchor: "parent", align: HorizontalAlign.Center },
bottom: { anchor: "parent", align: VerticalAlign.Bottom }
})消息图标的关键属性设置:
属性 | 值 | 说明 |
|---|---|---|
width | 24 | 宽度为24vp |
height | 24 | 高度为24vp |
id | “message” | 组件的唯一标识符,用于链式布局引用 |
alignRules.left | { anchor: “parent”, align: HorizontalAlign.Center } | 左侧对齐父容器的中心 |
alignRules.bottom | { anchor: “parent”, align: VerticalAlign.Bottom } | 底部对齐父容器的底部 |
消息图标被定位在容器的底部中心位置。
Image($r('app.media.profile'))
.width(24)
.height(24)
.id("profile")
.alignRules({
left: { anchor: "parent", align: HorizontalAlign.End },
bottom: { anchor: "parent", align: VerticalAlign.Bottom }
})我的图标的关键属性设置:
属性 | 值 | 说明 |
|---|---|---|
width | 24 | 宽度为24vp |
height | 24 | 高度为24vp |
id | “profile” | 组件的唯一标识符,用于链式布局引用 |
alignRules.left | { anchor: “parent”, align: HorizontalAlign.End } | 左侧对齐父容器的右侧 |
alignRules.bottom | { anchor: “parent”, align: VerticalAlign.Bottom } | 底部对齐父容器的底部 |
我的图标被定位在容器的右下角。
RelativeContainer提供了多种链式布局样式:
链式样式 | 说明 | 效果 |
|---|---|---|
ChainStyle.SPREAD | 均匀分布,组件之间的间距相等 | 组件均匀分布在容器中 |
ChainStyle.SPREAD_INSIDE | 两端对齐,首尾组件贴近容器边缘,中间组件均匀分布 | 首尾组件贴边,中间均匀分布 |
ChainStyle.PACKED | 紧凑排列,组件紧密排列在一起 | 组件紧密排列在容器中心 |
可以通过设置链的偏移(bias)来调整链在容器中的位置:
.chainMode([
{
id: "horizontalChain",
direction: Direction.HORIZONTAL,
style: ChainStyle.SPREAD,
components: ["home", "message", "profile"],
bias: 0.3 // 链向左偏移
}
])除了水平链,还可以创建垂直链:
.chainMode([
{
id: "verticalChain",
direction: Direction.VERTICAL,
style: ChainStyle.SPREAD,
components: ["button1", "button2", "button3"]
}
])可以在同一个容器中定义多个链,实现复杂的布局:
.chainMode([
{
id: "horizontalChain1",
direction: Direction.HORIZONTAL,
style: ChainStyle.SPREAD,
components: ["home", "message", "profile"]
},
{
id: "verticalChain1",
direction: Direction.VERTICAL,
style: ChainStyle.SPREAD,
components: ["header", "content", "footer"]
}
])底部导航栏通常包含图标和文本标签,可以使用以下方式布局:
布局方式 | 实现方法 |
|---|---|
图标在上,文本在下 | 使用垂直链连接每个导航项的图标和文本 |
只显示图标 | 只使用图标组件,通过水平链均匀分布 |
图标和文本并排 | 使用水平链连接图标和文本,再使用另一个水平链连接多个导航项 |
可以通过状态变量控制导航项的选中状态:
@State currentTab: number = 0;
// 在构建函数中
Image(this.currentTab === 0 ? $r('app.media.home_selected') : $r('app.media.home'))
.width(24)
.height(24)
.id("home")
.onClick(() => {
this.currentTab = 0;
})水平链布局在以下场景中特别有用:
链式布局是RelativeContainer提供的强大功能,特别适合创建均匀分布的组件布局。