1# Tabs 2 3通过页签进行内容视图切换的容器组件,每个页签对应一个内容视图。 4 5> **说明:** 6> 7> 该组件从API Version 7开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 8 9 10## 子组件 11 12仅可包含子组件[TabContent](ts-container-tabcontent.md)。 13 14> **说明:** 15> 16> Tabs子组件的visibility属性设置为None,或者visibility属性设置为Hidden时,对应子组件不显示,但依然会在视窗内占位。 17 18 19## 接口 20 21Tabs(value?: {barPosition?: BarPosition, index?: number, controller?: TabsController}) 22 23**参数:** 24 25| 参数名 | 参数类型 | 必填 | 参数描述 | 26| ----------- | --------------------------------- | ---- | ---------------------------------------- | 27| barPosition | [BarPosition](#barposition枚举说明)| 否 | 设置Tabs的页签位置。<br/>默认值:BarPosition.Start | 28| index | number | 否 | 设置当前显示页签的索引。<br/>默认值:0<br/>**说明:** <br/>设置为小于0的值时按默认值显示。<br/>可选值为[0, TabContent子节点数量-1]。<br/>设置不同值时,默认生效切换动效,可以设置animationDuration为0关闭动画。<br />从API version 10开始,该参数支持[$$](../../quick-start/arkts-two-way-sync.md)双向绑定变量。 | 29| controller | [TabsController](#tabscontroller) | 否 | 设置Tabs控制器。 | 30 31## BarPosition枚举说明 32 33| 名称 | 描述 | 34| ----- | ---------------------------------------- | 35| Start | vertical属性方法设置为true时,页签位于容器左侧;vertical属性方法设置为false时,页签位于容器顶部。 | 36| End | vertical属性方法设置为true时,页签位于容器右侧;vertical属性方法设置为false时,页签位于容器底部。 | 37 38 39## 属性 40 41除支持[通用属性](ts-universal-attributes-size.md)外,还支持以下属性: 42 43| 名称 | 参数类型 | 描述 | 44| -------------------------------- | ---------------------------------------- | ---------------------------------------- | 45| vertical | boolean | 设置为false是为横向Tabs,设置为true时为纵向Tabs。<br/>默认值:false | 46| scrollable | boolean | 设置为true时可以通过滑动页面进行页面切换,为false时不可滑动切换页面。<br/>默认值:true | 47| barMode | [BarMode](#barmode枚举说明),[ScrollableBarModeOptions](#scrollablebarmodeoptions10对象说明) | TabBar布局模式,BarMode为必选项,ScrollableBarModeOptions为可选项,具体描述见BarMode枚举说明、ScrollableBarModeOptions对象说明。从API version 10开始,支持ScrollableBarModeOptions参数。其中ScrollableBarModeOptions参数仅Scrollable模式下有效,非必填参数。<br/>默认值:BarMode.Fixed | 48| barWidth | number \| Length<sup>8+</sup> | TabBar的宽度值。<br/>默认值:<br/>未设置[SubTabBarStyle](ts-container-tabcontent.md#subtabbarstyle9)和[BottomTabBarStyle](ts-container-tabcontent.md#bottomtabbarstyle9)的TabBar且vertical属性为false时,默认值为Tabs的宽度。<br/>未设置[SubTabBarStyle](ts-container-tabcontent.md#subtabbarstyle9)和[BottomTabBarStyle](ts-container-tabcontent.md#bottomtabbarstyle9)的TabBar且vertical属性为true时,默认值为56vp。<br/>设置SubTabbarStyle样式且vertical属性为false时,默认值为Tabs的宽度。<br/>设置SubTabbarStyle样式且vertical属性为true时,默认值为56vp。<br/>设置BottomTabbarStyle样式且vertical属性为true时,默认值为96vp。<br/>设置BottomTabbarStyle样式且vertical属性为false时,默认值为Tabs的宽度。<br/>**说明:** <br/>设置为小于0或大于Tabs宽度值时,按默认值显示。 | 49| barHeight | number \| Length<sup>8+</sup> | TabBar的高度值。<br/>默认值:<br/>未设置带样式的TabBar且vertical属性为false时,默认值为56vp。<br/>未设置带样式的TabBar且vertical属性为true时,默认值为Tabs的高度。<br/>设置SubTabbarStyle样式且vertical属性为false时,默认值为56vp。<br/>设置SubTabbarStyle样式且vertical属性为true时,默认值为Tabs的高度。<br/>设置BottomTabbarStyle样式且vertical属性为true时,默认值为Tabs的高度。<br/>设置BottomTabbarStyle样式且vertical属性为false时,默认值为56vp。<br/>**说明:** <br/>设置为小于0或大于Tabs高度值时,按默认值显示。 | 50| animationDuration | number | 点击TabBar页签切换TabContent的动画时长。不设置时,点击TabBar页签切换TabContent无动画。<br/>默认值:300 <br/>**说明:** <br/>该参数不支持百分比设置;设置为小于0时,按默认值300ms显示。 | 51| divider<sup>10+</sup> | [DividerStyle](#dividerstyle10对象说明) \| null | 用于设置区分TabBar和TabContent的分割线样式设置分割线样式,默认不显示分割线。<br/> DividerStyle: 分割线的样式;<br/> null: 不显示分割线。 | 52| fadingEdge<sup>10+</sup> | boolean | 设置页签超过容器宽度时是否渐隐消失。<br />默认值:true <br/>**说明:** <br/>建议配合barBackgroundColor属性一起使用,如果barBackgroundColor属性没有定义,会默认显示页签末端为白色的渐隐效果。 | 53| barOverlap<sup>10+</sup> | boolean | 设置TabBar是否背后变模糊并叠加在TabContent之上。<br />默认值:false | 54| barBackgroundColor<sup>10+</sup> | [ResourceColor](ts-types.md#resourcecolor) | 设置TabBar的背景颜色。<br />默认值:透明 | 55| barGridAlign<sup>10+</sup> | [BarGridColumnOptions](#bargridcolumnoptions10对象说明) | 以栅格化方式设置TabBar的可见区域。具体参见BarGridColumnOptions对象。仅水平模式下有效,[不适用于XS、XL和XXL设备](../../ui/arkts-layout-development-grid-layout.md#栅格系统断点)。 | 56 57## DividerStyle<sup>10+</sup>对象说明 58 59| 名称 | 参数类型 | 必填 | 描述 | 60| ----------- | ---------------------------------------- | ---- | ---------------------------------------- | 61| strokeWidth | [Length](ts-types.md#length) | 是 | 分割线的线宽(不支持百分比设置)。 | 62| color | [ResourceColor](ts-types.md#resourcecolor) | 否 | 分割线的颜色。<br/>默认值:#33182431 | 63| startMargin | [Length](ts-types.md#length) | 否 | 分割线与侧边栏顶端的距离(不支持百分比设置)。<br/>默认值:0.0<br/>单位:vp | 64| endMargin | [Length](ts-types.md#length) | 否 | 分割线与侧边栏底端的距离(不支持百分比设置)。<br/>默认值:0.0<br/>单位:vp | 65 66## BarGridColumnOptions<sup>10+</sup>对象说明 67 68| 名称 | 参数类型 | 必填 | 描述 | 69| ----------- | ---------------------------------------- | ---- | ---------------------------------------- | 70| margin | [Dimension](ts-types.md#dimension10) | 否 | 网格模式下的column边距(不支持百分比设置)。<br/>默认值:24.0<br/>单位:vp | 71| gutter | [Dimension](ts-types.md#dimension10) | 否 | 网格模式下的column间隔(不支持百分比设置)。<br/>默认值:24.0<br/>单位:vp | 72| sm | number | 否 | 小屏下,页签占用的columns数量,必须是非负偶数。小屏为大于等于320vp但小于600vp。<br/>默认值为-1,代表页签占用TabBar全部宽度。 | 73| md | number | 否 | 中屏下,页签占用的columns数量,必须是非负偶数。中屏为大于等于600vp但小于800vp。<br/>默认值为-1,代表页签占用TabBar全部宽度。 | 74| lg | number | 否 | 大屏下,页签占用的columns数量,必须是非负偶数。大屏为大于等于840vp但小于1024vp。<br/>默认值为-1,代表页签占用TabBar全部宽度。 | 75 76## ScrollableBarModeOptions<sup>10+</sup>对象说明 77 78| 名称 | 参数类型 | 必填 | 描述 | 79| ----------- | ---------------------------------------- | ---- | ---------------------------------------- | 80| margin | [Dimension](ts-types.md#dimension10) | 否 | Scrollable模式下的TabBar的左右边距(不支持百分比设置)。<br/>默认值:0.0<br/>单位:vp | 81| nonScrollableLayoutStyle | [LayoutStyle](#layoutstyle10枚举说明) | 否 | Scrollable模式下不滚动时的页签排布方式。<br/>默认值:LayoutStyle.ALWAYS_CENTER | 82 83## BarMode枚举说明 84 85| 名称 | 描述 | 86| ---------- | ---------------------------------------- | 87| Scrollable | 每一个TabBar均使用实际布局宽度,超过总长度(横向Tabs的barWidth,纵向Tabs的barHeight)后可滑动。 | 88| Fixed | 所有TabBar平均分配barWidth宽度(纵向时平均分配barHeight高度)。 | 89 90## LayoutStyle<sup>10+</sup>枚举说明 91 92| 名称 | 描述 | 93| ---------- | ---------------------------------------- | 94| ALWAYS_CENTER | 当页签内容超过TabBar宽度时,TabBar可滚动。<br/>当页签内容不超过TabBar宽度时,TabBar不可滚动,页签紧凑居中。| 95| ALWAYS_AVERAGE_SPLITE | 当页签内容超过TabBar宽度时,TabBar可滚动。<br/>当页签内容不超过TabBar宽度时,TabBar不可滚动,且所有页签平均分配TabBar宽度。<br/>仅水平模式下有效,否则视为LayoutStyle.ALWAYS_CENTER。| 96| SPACE_BETWEEN_OR_CENTER | 当页签内容超过TabBar宽度时,TabBar可滚动。<br/>当页签内容不超过TabBar宽度但超过TabBar宽度一半时,TabBar不可滚动,页签紧凑居中。<br/>当页签内容不超过TabBar宽度一半时,TabBar不可滚动,保证页签居中排列在TabBar宽度一半,且间距相同。| 97 98## 事件 99 100除支持[通用事件](ts-universal-events-click.md)外,还支持以下事件: 101 102| 名称 | 功能描述 | 103| ---------------------------------------- | ---------------------------------------- | 104| onChange(event: (index: number) => void) | Tab页签切换后触发的事件。<br>- index:当前显示的index索引,索引从0开始计算。<br/>触发该事件的条件:<br/>1、TabContent支持滑动时,组件触发滑动时触发。<br/>2、通过[控制器](#tabscontroller)API接口调用。<br/>3、通过[状态变量](../../quick-start/arkts-state.md)构造的属性值进行修改。<br/>4、通过页签处点击触发。 | 105| onTabBarClick(event: (index: number) => void)<sup>10+</sup> | Tab页签点击后触发的事件。<br>- index:被点击的index索引,索引从0开始计算。<br/>触发该事件的条件:<br/>通过页签处点击触发。 | 106 107## TabsController 108 109Tabs组件的控制器,用于控制Tabs组件进行页签切换。不支持一个TabsController控制多个Tabs组件。 110 111### 导入对象 112 113```ts 114let controller: TabsController = new TabsController() 115``` 116 117### changeIndex 118 119changeIndex(value: number): void 120 121控制Tabs切换到指定页签。 122 123**参数:** 124 125| 参数名 | 参数类型 | 必填 | 参数描述 | 126| ----- | ------ | ---- | ---------------------------------------- | 127| value | number | 是 | 页签在Tabs里的索引值,索引值从0开始。<br/>**说明:** <br/>设置小于0或大于最大数量的值时,取默认值0。 | 128 129 130## 示例 131 132### 示例1 133 134```ts 135// xxx.ets 136@Entry 137@Component 138struct TabsExample { 139 @State fontColor: string = '#182431' 140 @State selectedFontColor: string = '#007DFF' 141 @State currentIndex: number = 0 142 private controller: TabsController = new TabsController() 143 144 @Builder tabBuilder(index: number, name: string) { 145 Column() { 146 Text(name) 147 .fontColor(this.currentIndex === index ? this.selectedFontColor : this.fontColor) 148 .fontSize(16) 149 .fontWeight(this.currentIndex === index ? 500 : 400) 150 .lineHeight(22) 151 .margin({ top: 17, bottom: 7 }) 152 Divider() 153 .strokeWidth(2) 154 .color('#007DFF') 155 .opacity(this.currentIndex === index ? 1 : 0) 156 }.width('100%') 157 } 158 159 build() { 160 Column() { 161 Tabs({ barPosition: BarPosition.Start, index: this.currentIndex, controller: this.controller }) { 162 TabContent() { 163 Column().width('100%').height('100%').backgroundColor('#00CB87') 164 }.tabBar(this.tabBuilder(0, 'green')) 165 166 TabContent() { 167 Column().width('100%').height('100%').backgroundColor('#007DFF') 168 }.tabBar(this.tabBuilder(1, 'blue')) 169 170 TabContent() { 171 Column().width('100%').height('100%').backgroundColor('#FFBF00') 172 }.tabBar(this.tabBuilder(2, 'yellow')) 173 174 TabContent() { 175 Column().width('100%').height('100%').backgroundColor('#E67C92') 176 }.tabBar(this.tabBuilder(3, 'pink')) 177 } 178 .vertical(false) 179 .barMode(BarMode.Fixed) 180 .barWidth(360) 181 .barHeight(56) 182 .animationDuration(400) 183 .onChange((index: number) => { 184 this.currentIndex = index 185 }) 186 .width(360) 187 .height(296) 188 .margin({ top: 52 }) 189 .backgroundColor('#F1F3F5') 190 }.width('100%') 191 } 192} 193``` 194 195 196 197### 示例2 198 199```ts 200// xxx.ets 201@Entry 202@Component 203struct TabsDivider1 { 204 private controller1: TabsController = new TabsController() 205 @State dividerColor: string = 'red' 206 @State strokeWidth: number = 2 207 @State startMargin: number = 0 208 @State endMargin: number = 0 209 @State nullFlag: boolean = false 210 211 build() { 212 Column() { 213 Tabs({ controller: this.controller1 }) { 214 TabContent() { 215 Column().width('100%').height('100%').backgroundColor(Color.Pink) 216 }.tabBar('pink') 217 218 TabContent() { 219 Column().width('100%').height('100%').backgroundColor(Color.Yellow) 220 }.tabBar('yellow') 221 222 TabContent() { 223 Column().width('100%').height('100%').backgroundColor(Color.Blue) 224 }.tabBar('blue') 225 226 TabContent() { 227 Column().width('100%').height('100%').backgroundColor(Color.Green) 228 }.tabBar('green') 229 230 TabContent() { 231 Column().width('100%').height('100%').backgroundColor(Color.Red) 232 }.tabBar('red') 233 } 234 .vertical(true) 235 .scrollable(true) 236 .barMode(BarMode.Fixed) 237 .barWidth(70) 238 .barHeight(200) 239 .animationDuration(400) 240 .onChange((index: number) => { 241 console.info(index.toString()) 242 }) 243 .height('200vp') 244 .margin({ bottom: '12vp' }) 245 .divider(this.nullFlag ? null : { 246 strokeWidth: this.strokeWidth, 247 color: this.dividerColor, 248 startMargin: this.startMargin, 249 endMargin: this.endMargin 250 }) 251 252 Button('常规Divider').width('100%').margin({ bottom: '12vp' }) 253 .onClick(() => { 254 this.nullFlag = false; 255 this.strokeWidth = 2; 256 this.dividerColor = 'red'; 257 this.startMargin = 0; 258 this.endMargin = 0; 259 }) 260 Button('空Divider').width('100%').margin({ bottom: '12vp' }) 261 .onClick(() => { 262 this.nullFlag = true 263 }) 264 Button('颜色变为蓝色').width('100%').margin({ bottom: '12vp' }) 265 .onClick(() => { 266 this.dividerColor = 'blue' 267 }) 268 Button('宽度增加').width('100%').margin({ bottom: '12vp' }) 269 .onClick(() => { 270 this.strokeWidth += 2 271 }) 272 Button('宽度减小').width('100%').margin({ bottom: '12vp' }) 273 .onClick(() => { 274 if (this.strokeWidth > 2) { 275 this.strokeWidth -= 2 276 } 277 }) 278 Button('上边距增加').width('100%').margin({ bottom: '12vp' }) 279 .onClick(() => { 280 this.startMargin += 2 281 }) 282 Button('上边距减少').width('100%').margin({ bottom: '12vp' }) 283 .onClick(() => { 284 if (this.startMargin > 2) { 285 this.startMargin -= 2 286 } 287 }) 288 Button('下边距增加').width('100%').margin({ bottom: '12vp' }) 289 .onClick(() => { 290 this.endMargin += 2 291 }) 292 Button('下边距减少').width('100%').margin({ bottom: '12vp' }) 293 .onClick(() => { 294 if (this.endMargin > 2) { 295 this.endMargin -= 2 296 } 297 }) 298 }.padding({ top: '24vp', left: '24vp', right: '24vp' }) 299 } 300} 301``` 302 303 304 305### 示例3 306 307```ts 308// xxx.ets 309@Entry 310@Component 311struct TabsOpaque { 312 @State message: string = 'Hello World' 313 private controller: TabsController = new TabsController() 314 private controller1: TabsController = new TabsController() 315 @State selfFadingFade: boolean = true; 316 317 build() { 318 Column() { 319 Button('子页签设置渐隐').width('100%').margin({ bottom: '12vp' }) 320 .onClick((event?: ClickEvent) => { 321 this.selfFadingFade = true; 322 }) 323 Button('子页签设置不渐隐').width('100%').margin({ bottom: '12vp' }) 324 .onClick((event?: ClickEvent) => { 325 this.selfFadingFade = false; 326 }) 327 Tabs({ barPosition: BarPosition.End, controller: this.controller }) { 328 TabContent() { 329 Column().width('100%').height('100%').backgroundColor(Color.Pink) 330 }.tabBar('pink') 331 332 TabContent() { 333 Column().width('100%').height('100%').backgroundColor(Color.Yellow) 334 }.tabBar('yellow') 335 336 TabContent() { 337 Column().width('100%').height('100%').backgroundColor(Color.Blue) 338 }.tabBar('blue') 339 340 TabContent() { 341 Column().width('100%').height('100%').backgroundColor(Color.Green) 342 }.tabBar('green') 343 344 TabContent() { 345 Column().width('100%').height('100%').backgroundColor(Color.Green) 346 }.tabBar('green') 347 348 TabContent() { 349 Column().width('100%').height('100%').backgroundColor(Color.Green) 350 }.tabBar('green') 351 352 TabContent() { 353 Column().width('100%').height('100%').backgroundColor(Color.Green) 354 }.tabBar('green') 355 356 TabContent() { 357 Column().width('100%').height('100%').backgroundColor(Color.Green) 358 }.tabBar('green') 359 } 360 .vertical(false) 361 .scrollable(true) 362 .barMode(BarMode.Scrollable) 363 .barHeight(80) 364 .animationDuration(400) 365 .onChange((index: number) => { 366 console.info(index.toString()) 367 }) 368 .fadingEdge(this.selfFadingFade) 369 .height('30%') 370 .width('100%') 371 372 Tabs({ barPosition: BarPosition.Start, controller: this.controller1 }) { 373 TabContent() { 374 Column().width('100%').height('100%').backgroundColor(Color.Pink) 375 }.tabBar('pink') 376 377 TabContent() { 378 Column().width('100%').height('100%').backgroundColor(Color.Yellow) 379 }.tabBar('yellow') 380 381 TabContent() { 382 Column().width('100%').height('100%').backgroundColor(Color.Blue) 383 }.tabBar('blue') 384 385 TabContent() { 386 Column().width('100%').height('100%').backgroundColor(Color.Green) 387 }.tabBar('green') 388 389 TabContent() { 390 Column().width('100%').height('100%').backgroundColor(Color.Green) 391 }.tabBar('green') 392 393 TabContent() { 394 Column().width('100%').height('100%').backgroundColor(Color.Green) 395 }.tabBar('green') 396 } 397 .vertical(true) 398 .scrollable(true) 399 .barMode(BarMode.Scrollable) 400 .barHeight(200) 401 .barWidth(80) 402 .animationDuration(400) 403 .onChange((index: number) => { 404 console.info(index.toString()) 405 }) 406 .fadingEdge(this.selfFadingFade) 407 .height('30%') 408 .width('100%') 409 } 410 .padding({ top: '24vp', left: '24vp', right: '24vp' }) 411 } 412} 413``` 414 415 416 417### 示例4 418 419```ts 420// xxx.ets 421@Entry 422@Component 423struct barBackgroundColorTest { 424 private controller: TabsController = new TabsController() 425 @State barOverlap: boolean = true; 426 @State barBackgroundColor: string = '#88888888'; 427 428 build() { 429 Column() { 430 Button("barOverlap变化").width('100%').margin({ bottom: '12vp' }) 431 .onClick((event?: ClickEvent) => { 432 if (this.barOverlap) { 433 this.barOverlap = false; 434 } else { 435 this.barOverlap = true; 436 } 437 }) 438 439 Tabs({ barPosition: BarPosition.Start, index: 0, controller: this.controller }) { 440 TabContent() { 441 Column() { 442 Text(`barOverlap ${this.barOverlap}`).fontSize(16).margin({ top: this.barOverlap ? '56vp' : 0 }) 443 Text(`barBackgroundColor ${this.barBackgroundColor}`).fontSize(16) 444 }.width('100%').width('100%').height('100%') 445 .backgroundColor(Color.Pink) 446 } 447 .tabBar(new BottomTabBarStyle($r('sys.media.ohos_app_icon'), "1")) 448 449 TabContent() { 450 Column() { 451 Text(`barOverlap ${this.barOverlap}`).fontSize(16).margin({ top: this.barOverlap ? '56vp' : 0 }) 452 Text(`barBackgroundColor ${this.barBackgroundColor}`).fontSize(16) 453 }.width('100%').width('100%').height('100%') 454 .backgroundColor(Color.Yellow) 455 } 456 .tabBar(new BottomTabBarStyle($r('sys.media.ohos_app_icon'), "2")) 457 458 TabContent() { 459 Column() { 460 Text(`barOverlap ${this.barOverlap}`).fontSize(16).margin({ top: this.barOverlap ? '56vp' : 0 }) 461 Text(`barBackgroundColor ${this.barBackgroundColor}`).fontSize(16) 462 }.width('100%').width('100%').height('100%') 463 .backgroundColor(Color.Green) 464 } 465 .tabBar(new BottomTabBarStyle($r('sys.media.ohos_app_icon'), "3")) 466 } 467 .vertical(false) 468 .barMode(BarMode.Fixed) 469 .height('60%') 470 .barOverlap(this.barOverlap) 471 .scrollable(true) 472 .animationDuration(10) 473 .barBackgroundColor(this.barBackgroundColor) 474 } 475 .height(500) 476 .padding({ top: '24vp', left: '24vp', right: '24vp' }) 477 } 478} 479``` 480 481 482 483 484### 示例5 485 486```ts 487// xxx.ets 488@Entry 489@Component 490struct TabsExample5 { 491 private controller: TabsController = new TabsController() 492 @State gridMargin: number = 10 493 @State gridGutter: number = 10 494 @State sm: number = -2 495 @State clickedContent: string = ""; 496 497 build() { 498 Column() { 499 Row() { 500 Button("gridMargin+10 " + this.gridMargin) 501 .width('47%') 502 .height(50) 503 .margin({ top: 5 }) 504 .onClick((event?: ClickEvent) => { 505 this.gridMargin += 10 506 }) 507 .margin({ right: '6%', bottom: '12vp' }) 508 Button("gridMargin-10 " + this.gridMargin) 509 .width('47%') 510 .height(50) 511 .margin({ top: 5 }) 512 .onClick((event?: ClickEvent) => { 513 this.gridMargin -= 10 514 }) 515 .margin({ bottom: '12vp' }) 516 } 517 518 Row() { 519 Button("gridGutter+10 " + this.gridGutter) 520 .width('47%') 521 .height(50) 522 .margin({ top: 5 }) 523 .onClick((event?: ClickEvent) => { 524 this.gridGutter += 10 525 }) 526 .margin({ right: '6%', bottom: '12vp' }) 527 Button("gridGutter-10 " + this.gridGutter) 528 .width('47%') 529 .height(50) 530 .margin({ top: 5 }) 531 .onClick((event?: ClickEvent) => { 532 this.gridGutter -= 10 533 }) 534 .margin({ bottom: '12vp' }) 535 } 536 537 Row() { 538 Button("sm+2 " + this.sm) 539 .width('47%') 540 .height(50) 541 .margin({ top: 5 }) 542 .onClick((event?: ClickEvent) => { 543 this.sm += 2 544 }) 545 .margin({ right: '6%' }) 546 Button("sm-2 " + this.sm).width('47%').height(50).margin({ top: 5 }) 547 .onClick((event?: ClickEvent) => { 548 this.sm -= 2 549 }) 550 } 551 552 Text("点击内容:" + this.clickedContent).width('100%').height(200).margin({ top: 5 }) 553 554 555 Tabs({ barPosition: BarPosition.End, controller: this.controller }) { 556 TabContent() { 557 Column().width('100%').height('100%').backgroundColor(Color.Pink) 558 }.tabBar(BottomTabBarStyle.of($r("sys.media.ohos_app_icon"), "1")) 559 560 TabContent() { 561 Column().width('100%').height('100%').backgroundColor(Color.Green) 562 }.tabBar(BottomTabBarStyle.of($r("sys.media.ohos_app_icon"), "2")) 563 564 TabContent() { 565 Column().width('100%').height('100%').backgroundColor(Color.Blue) 566 }.tabBar(BottomTabBarStyle.of($r("sys.media.ohos_app_icon"), "3")) 567 } 568 .width('350vp') 569 .animationDuration(300) 570 .height('60%') 571 .barGridAlign({ sm: this.sm, margin: this.gridMargin, gutter: this.gridGutter }) 572 .backgroundColor(0xf1f3f5) 573 .onTabBarClick((index: number) => { 574 this.clickedContent += "now index " + index + " is clicked\n"; 575 }) 576 } 577 .width('100%') 578 .height(500) 579 .margin({ top: 5 }) 580 .padding('10vp') 581 } 582} 583``` 584 585 586 587### 示例6 588 589```ts 590// xxx.ets 591@Entry 592@Component 593struct TabsExample6 { 594 private controller: TabsController = new TabsController() 595 @State scrollMargin: number = 0 596 @State layoutStyle: LayoutStyle = LayoutStyle.ALWAYS_CENTER 597 @State text: string = "文本" 598 599 build() { 600 Column() { 601 Row() { 602 Button("scrollMargin+10 " + this.scrollMargin) 603 .width('47%') 604 .height(50) 605 .margin({ top: 5 }) 606 .onClick((event?: ClickEvent) => { 607 this.scrollMargin += 10 608 }) 609 .margin({ right: '6%', bottom: '12vp' }) 610 Button("scrollMargin-10 " + this.scrollMargin) 611 .width('47%') 612 .height(50) 613 .margin({ top: 5 }) 614 .onClick((event?: ClickEvent) => { 615 this.scrollMargin -= 10 616 }) 617 .margin({ bottom: '12vp' }) 618 } 619 620 Row() { 621 Button("文本增加 ") 622 .width('47%') 623 .height(50) 624 .margin({ top: 5 }) 625 .onClick((event?: ClickEvent) => { 626 this.text += '文本增加' 627 }) 628 .margin({ right: '6%', bottom: '12vp' }) 629 Button("文本重置") 630 .width('47%') 631 .height(50) 632 .margin({ top: 5 }) 633 .onClick((event?: ClickEvent) => { 634 this.text = "文本" 635 }) 636 .margin({ bottom: '12vp' }) 637 } 638 639 Row() { 640 Button("layoutStyle.ALWAYS_CENTER") 641 .width('100%') 642 .height(50) 643 .margin({ top: 5 }) 644 .fontSize(15) 645 .onClick((event?: ClickEvent) => { 646 this.layoutStyle = LayoutStyle.ALWAYS_CENTER; 647 }) 648 .margin({ bottom: '12vp' }) 649 } 650 651 Row() { 652 Button("layoutStyle.ALWAYS_AVERAGE_SPLIT") 653 .width('100%') 654 .height(50) 655 .margin({ top: 5 }) 656 .fontSize(15) 657 .onClick((event?: ClickEvent) => { 658 this.layoutStyle = LayoutStyle.ALWAYS_AVERAGE_SPLIT; 659 }) 660 .margin({ bottom: '12vp' }) 661 } 662 663 Row() { 664 Button("layoutStyle.SPACE_BETWEEN_OR_CENTER") 665 .width('100%') 666 .height(50) 667 .margin({ top: 5 }) 668 .fontSize(15) 669 .onClick((event?: ClickEvent) => { 670 this.layoutStyle = LayoutStyle.SPACE_BETWEEN_OR_CENTER; 671 }) 672 .margin({ bottom: '12vp' }) 673 } 674 675 Tabs({ barPosition: BarPosition.End, controller: this.controller }) { 676 TabContent() { 677 Column().width('100%').height('100%').backgroundColor(Color.Pink) 678 }.tabBar(SubTabBarStyle.of(this.text)) 679 680 TabContent() { 681 Column().width('100%').height('100%').backgroundColor(Color.Green) 682 }.tabBar(SubTabBarStyle.of(this.text)) 683 684 TabContent() { 685 Column().width('100%').height('100%').backgroundColor(Color.Blue) 686 }.tabBar(SubTabBarStyle.of(this.text)) 687 } 688 .animationDuration(300) 689 .height('60%') 690 .backgroundColor(0xf1f3f5) 691 .barMode(BarMode.Scrollable, { margin: this.scrollMargin, nonScrollableLayoutStyle: this.layoutStyle }) 692 } 693 .width('100%') 694 .height(500) 695 .margin({ top: 5 }) 696 .padding('24vp') 697 } 698} 699``` 700 701