在上一期内容中,我们讲述了如何安装鸿蒙开发使用的开发环境DevEco Studio3.1,并使用布局控件和基本的常用控件构建了一个登录页。今天,我们要构建一个标签页。因为标签页常常是一个App登陆后的第一个主页面,划分标签页将会让应用程序的功能模块显得更加分门别类的清晰。
-
准备工作
我们首先要打开华为集成开发环境DevEco Studio 3.1,在pages目录下创建一个名为main.ets的页面文件。创建好该文件之后,我们输入如下代码块:
@Entry
@Component
struct Main {
build(){
Column() {
}
.padding(0)
.height('100%')
.width('100%')
.backgroundColor('#B22222')
}
}
这里我们要解释一下,其中代码的@Entry它表示这是一个用来展示页面视图的入口,也就是说编译器看到这个代码,就知道是要渲染UI给用户。这里要强调一下,一个页面只允许有一个@Entry入口。@Component则表示下面是用户自定义组件,build()则表示开始构建组件,Column()表示该页面布局是纵向布局。
下面.padding(0)开始的代码段,都是Column布局控件的属性,表示整个容器铺满整个屏幕,背景颜色是浅蓝色。这样,我们就将构建Tab页面的容器做好了。
-
使用Tabs组件填充页面
接下来,我们在上面构建好的Column布局组件中填充Tabs组件。在这里,我们使用@Builder装饰器来声明一个Tabs组件。我们首先简单地来描述一下Tabs组件的基本组成,它首先由Tabs外容器和TabContent子内容页组成。就像下面的这段代码:
private controller: TabsController = new TabsController()//在build()和srtuct Main之间声明组件变量
build(){
Column(){
Tabs({ barPosition: BarPosition.End, controller: this.controller }) {
TabContent() {
Column().width('100%').height('100%').backgroundColor(Color.Green)
}.tabBar('green')
TabContent() {
Column().width('100%').height('100%').backgroundColor(Color.Blue)
}.tabBar('blue')
}
}
}
这样,我们就在Column容器组件中填充了一个有两个Tab子页面的Tabs组件页。我们分别用绿色和蓝色来表示。但这个时候,这个Tabs组件的子页面还无法通过点击子Tab页来切换。我们还需要下面这段代码来通过@Builder装饰器,构造一个生成自定义TabBar样式的函数,可以实现Tab页签在底部的效果。
@Builder TabBuilder(title: string, targetIndex: number, selectedImg: Resource, normalImg: Resource) { Column() { Image(this.currentIndex === targetIndex ? selectedImg : normalImg) .size({ width: 25, height: 25 }) Text(title) .fontColor(this.currentIndex === targetIndex ? '#1698CE' : '#6B6B6B') } .width('100%') .height(50) .justifyContent(FlexAlign.Center) .onClick(() => { this.currentIndex = targetIndex; this.tabsController.changeIndex(this.currentIndex); }); }
上面这段代码,仅跟在private controller: TabsController = new TabsController()//在build()和srtuct Main之间声明组件变量之后。
-
特别说明
这里面我们要特别说明一下Tabs组件中子页面的布局位置参数,一个是barPosition参数,另一个是vertical参数。其中BarPosition参数的枚举值BarPosition.End/Start决定了Tabs组件子组件布局位置的值,如果是Start则表示子Tab页是横向从左开始布局,也就是子页签靠左布局。反之,如果是End则表示是靠右布局。
vertical参数是一个布尔值参数,如果是true,配合barPosition: BarPosition.Start属性,则表示页签位于屏幕左侧。反之,如果vertical的值是false,且barPosition的值为End,则表示页签靠底部纵向显示。
我们把完整的代码贴出来:(里面用到的图片资源,读者可以自行添加)
@Entry @Component struct Main { private controller: TabsController = new TabsController() @State currentIndex: number = 0; @Builder TabBuilder(title: string, targetIndex: number, selectedImg: Resource, normalImg: Resource) { Column() { Image(this.currentIndex === targetIndex ? selectedImg : normalImg) .size({ width: 25, height: 25 }) Text(title) .fontColor(this.currentIndex === targetIndex ? '#1698CE' : '#6B6B6B') } .width('100%') .height(50) .justifyContent(FlexAlign.Center) .onClick(() => { this.currentIndex = targetIndex; this.tabsController.changeIndex(this.currentIndex); }) } build(){ Column() { Tabs({ barPosition: BarPosition.End, controller: this.tabsController }) { TabContent() { Column({ space: 1 }) { Navigation() .title('照明控制') .hideToolBar(true) .align(Alignment.Start) .titleMode(NavigationTitleMode.Mini) .backgroundColor(Color.Transparent) .width('100%') .margin({ top: 1, left: 12 }) .height(45) .borderColor(Color.White) } } .tabBar(this.TabBuilder('首页', 0, $r('app.media.home_selected'), $r('app.media.home_normal'))) TabContent() { Column().width('100%').height('100%').backgroundColor('#00CB87') } .tabBar(this.TabBuilder('设备', 0, $r('app.media.home_selected'), $r('app.media.home_normal'))) TabContent() { Column().width('100%').height('100%').backgroundColor('#007DFF') } .tabBar(this.TabBuilder('我的', 1, $r('app.media.mine_selected'), $r('app.media.mine_normal'))) } } .vertical(false) .barWidth('100%') .barHeight(50) .onChange((index: number) => { this.currentIndex = index; }) } .padding(0) .height('100%') .width('100%') .backgroundColor('#B22222') } }
-
Tabs子页的内容填充
Tabs组件的子页面填充不是本节的主要内容,我们可以使用我们在登录页设计中学到的基本控件,为Tabs的子页面填充。这个作业就留给各位读者了!下面我贴出来我的填充的子页面效果图: