一、Navication组件
Navigation组件一般作为Page页面的根容器,通过属性设置来展示页面的标题栏、工具栏、导航栏等。
- 子组件:可以包含子组件。从API Version 9开始,推荐与NavRouter组件搭配使用。
- 支持属性:除了通用属性外,还支持以下属性:title、subTitle、menus、titleMode、toolBar、hideToolBar、hideBackButton、navBarWidth、navBarPosition、mode、backButtonIcon、hideNavBar
- 事件:onTitleModeChange(callback: (titleMode: NavigationTitleMode) => void)、onNavBarStateChange(callback: (isVisible: boolean) => void)
二、Tabs
通过页签进行内容视图切换的容器组件,每个页签对应一个内容视图。
- 接口:Tabs(value?: {barPosition?: BarPosition, index?: number, controller?: TabsController})
- 支持属性:除了通用属性外,还支持以下属性:vertical、scrollable、barMode、barWidth、barHeight、animationDuration
- 事件:onChange(event: (index: number) => void)
- Controller:controller: TabsController = new TabsController()
三、自定义Navigation工具栏
Navigation的toolBar(object | CustomBuilder)用于设置工具栏内容。其参数可以是一个配置对象或者一个CustomBuilder,由于通过配置对象创建的toolBar为预设样式,所以当我们需要特殊定制toolBar的时候,就需要通过创建CustormBuilder来根据需求自己声明UI样式。例如本项目中的toolBar就需要图标和字体颜色与主题色同步。
实现思路:
- 首先将Tabs作为Navication的子组件
- 声明一个@State用于记录当前激活的位置,再声明一个TabController用于控制Tabs内容的切换
- 创建一个CustomBuilder并完成UI样式编写,然后为每一个切换按钮绑定onClick事件修改当前激活位置并调用tabController.changeIndex切换内容
- 最后将其作为参数传入toolBar
- 通常我们希望对Tabs的内容进行懒加载,当首次跳转某位置后才加载其内容。这时我们可以设置一个集合来记录每一个内容是否需要加载,例如:activeList = [false, false, false],当位置@State改变后将指定位置改为true。然后内容组件通过@Prop接收加载状态,当为true时加载内容,否则为等待动画
实现代码:(部分)
@Entry
@Component
struct Index{
// 当前激活位置
@State current: number = 0
// Tabs的Controller
private tabController: TabsController = new TabController()
// toolBar的数据
private toolBars: Array<string> = ["item", "item", "item"]
// 加载状态
@State activeList: Array<boolean> = this.toolBars.map(() => false)
build() {
Navigation() {
Tabs({
controller: this.tabController
}) {
ForEach(this.activeList, (isActive: boolean, index: number) => {
TabContent() {
// 已激活加载内容(这里简单举例)
if (isActive) {
Text(`我是内容${index}`)
} else {
Text("正在加载中...")
}
}
}, (_, index: number) => index.toString())
}
.barWidth(0)
.barHeight(0)
}
.toolBar(this.ToolBar)
}
// 自定义ToolBar
@Builder ToolBar() {
// 简单举例,具体以需求为准
Row() {
ForEach(this.toolBars, (item: string, index: number) => {
// 判断是否激活
if (this.current === index) {
// 这里可以设置激活样式
// 已激活不用添加点击事件
Text(item)
} else {
Text(item)
.onClick(() => {
// 更改激活位置
this.current = index
this.tabController.changeIndex(index)
!this.activeList[index] && (this.activeList[index] = true)
})
}
})
}
.justifyContent(FlexAlign.SpaceBetween)
}
}
四、总结
今天通过运用 Navication、Tabs、CustomBuilder等内容。简单的实现了一个自定义Navication的ToolBar。在实际的开发中,可以灵活的运用TabsController等完成对样式或功能的定制以满足项目的需求。