HarmonyOS 学习

avatar
作者
猴君
阅读量:0

基础组件的使用

Image组件的基本使用

Image组件用来渲染展示图片,它可以让界面变得更加丰富多彩。只需要给Image组件设置图片地址、宽和高,图片就能加载出来,示例如下:

Image($r("app.media.icon"))   .width(100)   .height(100)

设置缩放类型

为了使图片在页面中有更好的显示效果,有时候需要对图片进行缩放处理。可以使用objectFit属性设置图片的缩放类型,objectFit的参数类型为ImageFit

将图片加载到Image组件,设置宽高各100,设置objectFit为Cover(默认值),设置图片背景色为灰色0xCCCCCC。示例代码如下:

Image($r("app.media.image2"))   .objectFit(ImageFit.Cover)   .backgroundColor(0xCCCCCC)   .width(100)   .height(100) 

ImageFit包含以下几种类型:

  • Contain:保持宽高比进行缩小或者放大,使得图片完全显示在显示边界内。
  • Cover(默认值):保持宽高比进行缩小或者放大,使得图片两边都大于或等于显示边界。
  • Auto:自适应显示。
  • Fill:不保持宽高比进行放大缩小,使得图片充满显示边界。
  • ScaleDown:保持宽高比显示,图片缩小或者保持不变。
  • None:保持原有尺寸显示。

加载网络图片

比如浏览新闻的时候,图片一般从网络加载而来,Image组件支持加载网络图片,将图片地址换成网络图片地址进行加载。

Image('https://www.example.com/xxx.png')

为了成功加载网络图片,您需要在module.json5文件中申明网络访问权限。

{     "module" : {         "requestPermissions":[            {              "name": "ohos.permission.INTERNET"            }         ]     } }

Text组件的基本使用

Text组件用于在界面上展示一段文本信息,可以包含子组件Span。

文本样式

针对包含文本元素的组件,例如Text、Span、Button、TextInput等,可使用fontColor、fontSize、fontStyle、 fontWeight、fontFamily这些文本样式,分别设置文本的颜色、大小、样式、粗细以及字体,文本样式的属性如下表:

fontColor

ResourceColor

设置文本颜色。

fontSize

Length | Resource

设置文本尺寸,Length为number类型时,使用fp单位。

fontStyle

FontStyle

设置文本的字体样式。默认值:FontStyle.Normal。

fontWeight

number | FontWeight | string

设置文本的字体粗细,number类型取值[100, 900],取值间隔为100,默认为400,取值越大,字体越粗。string类型仅支持number类型取值的字符串形式,例如“400”,以及“bold”、“bolder”、“lighter”、“regular”、“medium”,分别对应FontWeight中相应的枚举值。默认值:FontWeight.Normal。

fontFamily

string | Resource

设置文本的字体列表。使用多个字体,使用“,”进行分割,优先级按顺序生效。例如:“Arial,sans-serif”。

下面示例代码中包含两个Text组件,第一个使用的是默认样式,第二个给文本设置了一些文本样式。

@Entry @Component struct TextTest{   build(){     Row(){       Column(){         Text('HarmonyOS')         Text('HarmonyOS')           .fontColor(Color.Blue)           .fontSize(20)           .fontStyle(FontStyle.Italic)           .fontWeight(FontWeight.Bold)           .fontFamily('Arial')       }.width('100%')     }.backgroundColor(0xF1F3F5).height('100%')   } } 

除了通用属性和文本样式设置,下面列举了一些Text组件的常用属性的使用。

设置文本对齐方式

使用textAlign属性可以设置文本的对齐方式,示例代码如下:

Text('HarmonyOS')   .width(200)   .textAlign(TextAlign.Start)   .backgroundColor(0xE6F2FD)

textAlign参数类型为TextAlign,定义了以下几种类型:

  • Start(默认值):水平对齐首部。
  • Center:水平居中对齐。
  • End:水平对齐尾部。

设置文本超长显示

当文本内容较多超出了Text组件范围的时候,您可以使用textOverflow设置文本截取方式,需配合maxLines使用,单独设置不生效,maxLines用于设置文本显示最大行数。下面的示例代码将textOverflow设置为Ellipsis ,它将显示不下的文本用 “...” 表示:

Text('This is the text content of Text Component This is the text content of Text Component')   .fontSize(16)   .maxLines(1)   .textOverflow({overflow:TextOverflow.Ellipsis})   .backgroundColor(0xE6F2FD) 

设置文本装饰线

使用decoration设置文本装饰线样式及其颜色。decoration包含type和color两个参数,其中type用于设置装饰线样式,参数类型为TextDecorationTyp,color为可选参数。

下面的示例代码给文本设置了下划线,下划线颜色为黑色:

Text('HarmonyOS')   .fontSize(20)   .decoration({ type: TextDecorationType.Underline, color: Color.Black })   .backgroundColor(0xE6F2FD)

TextDecorationTyp包含以下几种类型:

  • None:不使用文本装饰线。
  • Overline:文字上划线修饰。
  • LineThrough:穿过文本的修饰线。
  • Underline:文字下划线修饰。

TextInput组件的基本使用

TextInput组件用于输入单行文本,响应输入事件。TextInput的使用也非常广泛,例如应用登录账号密码、发送消息等。和Text组件一样,TextInput组件也支持文本样式设置,下面的示例代码实现了一个简单的输入框:

TextInput()   .fontColor(Color.Blue)   .fontSize(20)   .fontStyle(FontStyle.Italic)   .fontWeight(FontWeight.Bold)   .fontFamily('Arial') 

设置输入提示文本

当我们平时使用输入框的时候,往往会有一些提示文字。这种提示功能使用placeholder属性就可以轻松的实现。还可以使用placeholderColor和placeholderFont分别设置提示文本的颜色和样式,示例代码如下:

TextInput({ placeholder: '请输入帐号' })   .placeholderColor(0x999999)   .placeholderFont({ size: 20, weight: FontWeight.Medium, family: 'cursive', style: FontStyle.Italic })

设置输入类型

可以使用type属性来设置输入框类型。例如密码输入框,一般输入密码的时候,内容会显示为“......”,将type属性设置为InputType.Password就可以实现。示例代码如下:

TextInput({ placeholder: '请输入密码' })   .type(InputType.Password)

type的参数类型为InputType,包含以下几种输入类型:

  • Normal:基本输入模式。支持输入数字、字母、下划线、空格、特殊字符。
  • Password:密码输入模式。
  • Email:e-mail地址输入模式。
  • Number:纯数字输入模式。

设置光标位置

可以使用TextInputController动态设置光位置,下面的示例代码使用TextInputController的caretPosition方法,将光标移动到了第二个字符后。

@Entry @Component struct TextInputDemo {   controller: TextInputController = new TextInputController()     build() {     Column() {       TextInput({ controller: this.controller })       Button('设置光标位置')         .onClick(() => {           this.controller.caretPosition(2)         })     }     .height('100%')     .backgroundColor(0xE6F2FD)   } }

获取输入文本

我们可以给TextInput设置onChange事件,输入文本发生变化时触发回调,下面示例代码中的value为实时获取用户输入的文本信息。

@Entry @Component struct TextInputDemo {   @State text: string = ''     build() {     Column() {       TextInput({ placeholder: '请输入账号' })         .caretColor(Color.Blue)         .onChange((value: string) => {           this.text = value         })       Text(this.text)     }     .alignItems(HorizontalAlign.Center)     .padding(12)     .backgroundColor(0xE6F2FD)   } }

Button组件的基本使用

Button组件主要用来响应点击操作,可以包含子组件。下面的示例代码实现了一个“登录按钮”:

Button('登录', { type: ButtonType.Capsule, stateEffect: true })   .width('90%')   .height(40)   .fontSize(16)   .fontWeight(FontWeight.Medium)   .backgroundColor('#007DFF')

设置按钮样式

type用于定义按钮样式,示例代码中ButtonType.Capsule表示胶囊形按钮;stateEffect用于设置按钮按下时是否开启切换效果,当状态置为false时,点击效果关闭,默认值为true。

我们可以设置多种样式的Button,除了Capsule还可以设置Normal和Circle:

  • Capsule:胶囊型按钮(圆角默认为高度的一半)。
  • Circle:圆形按钮。
  • Normal:普通按钮(默认不带圆角)。

设置按钮点击事件

可以给Button绑定onClick事件,每当用户点击Button的时候,就会回调执行onClick方法,调用里面的逻辑代码。

Button('登录', { type: ButtonType.Capsule, stateEffect: true })   ...   .onClick(() => {   // 处理点击事件逻辑   })

包含子组件

Button组件可以包含子组件,让您可以开发出更丰富多样的Button,下面的示例代码中Button组件包含了一个Image组件:

Button({ type: ButtonType.Circle, stateEffect: true }) {   Image($r('app.media.icon_delete'))     .width(30)     .height(30) } .width(55) .height(55) .backgroundColor(0x317aff)

LoadingProgress的基本使用

 

LoadingProgress组件用于显示加载进展,比如应用的登录界面,当我们点击登录的时候,显示的“正在登录”的进度条状态。LoadingProgress的使用非常简单,只需要设置颜色和宽高就可以了。

LoadingProgress()   .color(Color.Blue)   .height(60)   .width(60)

使用资源引用类型

Resource是资源引用类型,用于设置组件属性的值。推荐大家优先使用Resource类型,将资源文件(字符串、图片、音频等)统一存放于resources目录下,便于开发者统一维护。同时系统可以根据当前配置加载合适的资源,例如,开发者可以根据屏幕尺寸呈现不同的布局效果,或根据语言设置提供不同的字符串。

例如下面的这段代码,直接在代码中写入了字符串和数字这样的硬编码。

Button('登录', { type: ButtonType.Capsule, stateEffect: true })   .width(300)   .height(40)   .fontSize(16)   .fontWeight(FontWeight.Medium)   .backgroundColor('#007DFF')

我们可以将这些硬编码写到entry/src/main/resources下的资源文件中。

在string.json中定义Button显示的文本。

{   "string": [     {       "name": "login_text",       "value": "登录"     }   ] }

在float.json中定义Button的宽高和字体大小。

{   "float": [     {       "name": "button_width",       "value": "300vp"     },     {       "name": "button_height",       "value": "40vp"     },     {       "name": "login_fontSize",       "value": "18fp"     }   ] }

在color.json中定义Button的背景颜色。

{   "color": [     {       "name": "button_color",       "value": "#1890ff"     }   ] }

然后在Button组件通过“$r('app.type.name')”的形式引用应用资源。app代表应用内resources目录中定义的资源;type代表资源类型(或资源的存放位置),可以取“color”、“float”、“string”、“plural”、“media”;name代表资源命名,由开发者定义资源时确定。

Button($r('app.string.login_text'), { type: ButtonType.Capsule })   .width($r('app.float.button_width'))   .height($r('app.float.button_height'))   .fontSize($r('app.float.login_fontSize'))   .backgroundColor($r('app.color.button_color'))

Column&Row组件的使用

接下来,我们将详细讲解Column和Row容器的两个属性justifyContent和alignItems。

justifyContent

设置子组件在主轴方向上的对齐格式。

alignItems

设置子组件在交叉轴方向上的对齐格式。

1. 主轴方向的对齐(justifyContent)

子组件在主轴方向上的对齐使用justifyContent属性来设置,其参数类型是FlexAlign。FlexAlign定义了以下几种类型:

  • Start:元素在主轴方向首端对齐,第一个元素与行首对齐,同时后续的元素与前一个对齐。
  • Center:元素在主轴方向中心对齐,第一个元素与行首的距离以及最后一个元素与行尾距离相同。
  • End:元素在主轴方向尾部对齐,最后一个元素与行尾对齐,其他元素与后一个对齐。
  • SpaceBetween:元素在主轴方向均匀分配弹性元素,相邻元素之间距离相同。 第一个元素与行首对齐,最后一个元素与行尾对齐。
  • SpaceAround:元素在主轴方向均匀分配弹性元素,相邻元素之间距离相同。 第一个元素到行首的距离和最后一个元素到行尾的距离是相邻元素之间距离的一半。
  • SpaceEvenly:元素在主轴方向等间距布局,无论是相邻元素还是边界元素到容器的间距都一样。

2. 交叉轴方向的对齐(alignItems)

子组件在交叉轴方向上的对齐方式使用alignItems属性来设置。

Column容器的主轴是垂直方向,交叉轴是水平方向,其参数类型为HorizontalAlign(水平对齐),HorizontalAlign定义了以下几种类型:

  • Start:设置子组件在水平方向上按照起始端对齐。
  • Center(默认值):设置子组件在水平方向上居中对齐。
  • End:设置子组件在水平方向上按照末端对齐。

Row容器的主轴是水平方向,交叉轴是垂直方向,其参数类型为VerticalAlign(垂直对齐),VerticalAlign定义了以下几种类型:

  • Top:设置子组件在垂直方向上居顶部对齐。
  • Center(默认值):设置子组件在竖直方向上居中对齐。
  • Bottom:设置子组件在竖直方向上居底部对齐。

接口介绍

Column和Row容器的接口。

Column

Column(value?:{space?: string | number})

Row

Row(value?:{space?: string | number})

Column和Row容器的接口都有一个可选参数space,表示子组件在主轴方向上的间距。

组件使用

我们来具体讲解如何高效的使用Column和Row容器组件来构建这个登录页面。

我们需要对页面进行拆解,先确定页面的布局,再分析页面上的内容分别使用哪些组件来实现。

我们仔细分析这个登录页面。在静态布局中,组件整体是从上到下布局的,因此构建该页面可以使用Column来构建。在此基础上,我们可以看到有部分内容在水平方向上由几个基础组件构成,例如页面中间的短信验证码登录与忘记密码以及页面最下方的其他方式登录,那么构建这些内容的时候,可以在Column组件中嵌套Row组件,继而在Row组件中实现水平方向的布局。

 

838e23ea6cf6ba228f8241fbd8dd8e06.png

根据上述页面拆解,在Column容器里,依次是Image、Text、TextInput、Button等基础组件,还有两组组件是使用Row容器组件来实现的,主要代码如下:

@Entry @Component export struct LoginPage {   build() {     Column() {       Image($r('app.media.logo'))         ...       Text($r('app.string.login_page'))         ...       Text($r('app.string.login_more'))         ...       TextInput({ placeholder: $r('app.string.account') })         ...       TextInput({ placeholder: $r('app.string.password') })         ...       Row() {         Text($r(…))          Text($r(…))        }       Button($r('app.string.login'), { type: ButtonType.Capsule, stateEffect: true })         ...       Row() {         this.imageButton($r(…))         this.imageButton($r(…))         this.imageButton($r(…))       }       ...     }     ...   } }

我们详细看一下使用Row容器的两组组件。

两个文本组件展示的内容是按水平方向布局的,使用两端对齐的方式。这里我们使用Row容器组件,并且需要配置主轴上(水平方向)的对齐格式justifyContent为FlexAlign.SpaceBetween(两端对齐)。

Row() {   Text($r(…))    Text($r(…))    }   .justifyContent(FlexAlign.SpaceBetween)   .width('100%')

其他登录方式的三个按钮也是按水平方向布局的,同样使用Row容器组件。这里按钮的间距是一致的,我们可以通过配置可选参数space来设置按钮间距,使子组件间距一致。

Row({ space: CommonConstants.LOGIN_METHODS_SPACE }) {   this.imageButton($r(…))   this.imageButton($r(…))   this.imageButton($r(…)) }

至此,这个登录页面的简单布局实现了。

List和Grid组件的使用

list组件的使用

List是很常用的滚动类容器组件,一般和子组件ListItem一起使用,List列表中的每一个条目对应一个ListItem组件。

使用ForEach渲染列表

列表往往由多个条目组成,所以我们需要在List组件中写多个ListItem组件来构建列表,这就会导致代码的冗余。使用循环渲染(ForEach)遍历数组的方式构建列表,可以减少重复代码。示例代码如下:

@Entry @Component struct ListDemo {   private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]    build() {     Column() {       List({ space: 10 }) {         ForEach(this.arr, (item: number) => {           ListItem() {             Text(`${item}`)               .width('100%')               .height(100)               .fontSize(20)               .fontColor(Color.White)               .textAlign(TextAlign.Center)               .borderRadius(10)               .backgroundColor(0x007DFF)           }         }, item => item)       }     }     .padding(12)     .height('100%')     .backgroundColor(0xF1F3F5)   } }

设置列表项分割线

List组件子组件ListItem之间默认是没有分割线的,部分场景子组件ListItem间需要设置分割线,这时候我们可以使用List组件的`divider`属性。`divider`属性包含四个参数:

  • strokeWidth: 分割线的线宽。
  • color: 分割线的颜色。
  • startMargin:分割线距离列表侧边起始端的距离。
  • endMargin: 分割线距离列表侧边结束端的距离。

List列表滚动事件监听

List组件提供了一系列事件方法用来监听列表的滚动,您可以根据需要,监听这些事件来做一些操作:

  • onScroll:列表滑动时触发,返回值scrollOffset为滑动偏移量,scrollState为当前滑动状态。
  • onScrollIndex:列表滑动时触发,返回值分别为滑动起始位置索引值与滑动结束位置索引值。
  • onReachStart:列表到达起始位置时触发。
  • onReachEnd:列表到底末尾位置时触发。
  • onScrollStop:列表滑动停止时触发。

使用示例代码如下:

List({ space: 10 }) {   ForEach(this.arr, (item) => {     ListItem() {       Text(`${item}`)         ...     }.editable(true)   }, item => item) } .editMode(this.editFlag) .onScrollIndex((firstIndex: number, lastIndex: number) => {   console.info('first' + firstIndex)   console.info('last' + lastIndex) }) .onScroll((scrollOffset: number, scrollState: ScrollState) => {   console.info('scrollOffset' + scrollOffset)   console.info('scrollState' + scrollState) }) .onReachStart(() => {   console.info('onReachStart') }) .onReachEnd(() => {   console.info('onReachEnd') }) .onScrollStop(() => {   console.info('onScrollStop') })

设置List排列方向

List组件里面的列表项默认是按垂直方向排列的,如果您想让列表沿水平方向排列,您可以将List组件的`listDirection`属性设置为`Axis.Horizontal`。

listDirection参数类型是Axis,定义了以下两种类型:

  • Vertical(默认值):子组件ListItem在List容器组件中呈纵向排列。
  • Horizontal:子组件ListItem在List容器组件中呈横向排列。

Grid组件的使用

Grid组件简介

Grid组件为网格容器,是一种网格列表,由“行”和“列”分割的单元格所组成,通过指定“项目”所在的单元格做出各种各样的布局。Grid组件一般和子组件GridItem一起使用,Grid列表中的每一个条目对应一个GridItem组件。

使用ForEach渲染网格布局

和List组件一样,Grid组件也可以使用ForEach来渲染多个列表项GridItem。我们通过下面的这段示例代码来介绍Grid组件的使用。

@Entry @Component struct GridExample {   private arr: String[] = ['0', '1', '2', '3']    build() {     Column() {       Grid() {         ForEach(this.arr, (day: string) => {           ForEach(this.arr, (day: string) => {             GridItem() {               Text(day)                 .fontSize(16)                 .fontColor(Color.White)                 .backgroundColor(0x007DFF)                 .width('100%')                 .height('100%')                 .textAlign(TextAlign.Center)             }           }, day => day)         }, day => day)       }       .columnsTemplate('1fr 1fr 1fr 1fr')       .rowsTemplate('1fr 1fr 1fr 1fr')       .columnsGap(10)       .rowsGap(10)       .height(300)     }     .width('100%')     .padding(12)     .backgroundColor(0xF1F3F5)   } }

示例代码效果图如下:

 

a61d688334b353f81f22740575a3c16a.png

可以看出效果图中Grid列表的列表项刚好铺满整个Grid组件,列表是不能滚动的,我们手机常用的应用中经常会见到可以滚动的Grid列表,比如商品列表。设置列表项GridItem的高度为固定值,例如100;不设置rowsTemplate属性,就可以实现Grid列表的滚动:

Grid() {   ForEach(this.arr, (day: string) => {     ForEach(this.arr, (day: string) => {       GridItem() {         Text(day)           ...       }     }, day => day)   }, day => day) } .columnsTemplate('1fr 1fr 1fr 1fr') .columnsGap(10) .rowsGap(10) .height(300)

此外,Grid像List一样也可以使用onScrollIndex来监听列表的滚动。

Tabs组件的使用

ArkUI开发框架提供了一种页签容器组件Tabs,开发者通过Tabs组件可以很容易的实现内容视图的切换。页签容器Tabs的形式多种多样,不同的页面设计页签不一样,可以把页签设置在底部、顶部或者侧边。

Tabs组件的简单使用

Tabs组件仅可包含子组件TabContent,每一个页签对应一个内容视图即TabContent组件。下面的示例代码构建了一个简单的页签页面:

@Entry @Component struct TabsExample {   private controller: TabsController = new TabsController()    build() {     Column() {       Tabs({ barPosition: BarPosition.Start, 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')          TabContent() {           Column().width('100%').height('100%').backgroundColor(Color.Yellow)         }         .tabBar('yellow')          TabContent() {           Column().width('100%').height('100%').backgroundColor(Color.Pink)         }         .tabBar('pink')       }       .barWidth('100%') // 设置TabBar宽度       .barHeight(60) // 设置TabBar高度       .width('100%') // 设置Tabs组件宽度       .height('100%') // 设置Tabs组件高度       .backgroundColor(0xF5F5F5) // 设置Tabs组件背景颜色     }     .width('100%')     .height('100%')   } }

上面示例代码中,Tabs组件中包含4个子组件TabContent,通过TabContent的`tabBar`属性设置TabBar的显示内容。使用通用属性width和height设置了Tabs组件的宽高,使用barWidth和barHeight设置了TabBar的宽度和高度。

  • TabContent组件不支持设置通用宽度属性,其宽度默认撑满Tabs父组件。
  • TabContent组件不支持设置通用高度属性,其高度由Tabs父组件高度与TabBar组件高度决定。

设置TabBar布局模式

因为Tabs的布局模式默认是Fixed的,所以Tabs的页签是不可滑动的。当页签比较多的时候,可能会导致页签显示不全,将布局模式设置为Scrollable的话,可以实现页签的滚动。

Tabs的布局模式有Fixed(默认)和Scrollable两种:

  • BarMode.Fixed:所有TabBar平均分配barWidth宽度(纵向时平均分配barHeight高度),页签不可滚动。
  • BarMode.Scrollable:每一个TabBar均使用实际布局宽度,超过总长度(横向Tabs的barWidth,纵向Tabs的barHeight)后可滑动。

当页签比较多的时候,可以滑动页签,下面的示例代码将barMode设置为BarMode.Scrollable,实现了可滚动的页签:

设置TabBar位置和排列方向

Tabs组件页签默认显示在顶部,某些场景下您可能希望Tabs页签出现在底部或者侧边,您可以使用Tabs组件接口中的参数barPosition设置页签位置。此外页签显示位置还与`vertical`属性相关联,`vertical`属性用于设置页签的排列方向,当`vertical`的属性值为false(默认值)时页签横向排列,为true时页签纵向排列。

barPosition的值可以设置为BarPosition.Start(默认值)和BarPosition.End:

设置为BarPositon.Start且vertical为false时页签位于容器顶部,设置为BarPositon.Start且vertical为true时页签位于容器左侧,设置为BarPosition.End且vertical为false时页签位于容器底部,设置为BarPosition.End且vertical为true时页签位于容器右侧。

四种代码分别如下:

//BarPosition.Start且vertical为`false`  Tabs({ barPosition: BarPosition.Start }) {   ... } .vertical(false)  .barWidth('100%')  .barHeight(60)    //BarPosition.Start且vertical为`true`  Tabs({ barPosition: BarPosition.Start }) {   ... } .vertical(true)  .barWidth(100)  .barHeight(200)    // BarPosition.End且vertical为`false` Tabs({ barPosition: BarPosition.End }) {   ... } .vertical(false)  .barWidth('100%')  .barHeight(60)  // BarPosition.End且vertical为`true` Tabs({ barPosition: BarPosition.End}) {   ... } .vertical(true)  .barWidth(100)  .barHeight(200)

自定义TabBar样式

TabBar的默认效果已经展示了。

往往开发过程中,UX给我们的设计效果可能并不是这样的。

TabContent的tabBar属性除了支持string类型,还支持使用@Builder装饰器修饰的函数。您可以使用@Builder装饰器,构造一个生成自定义TabBar样式的函数,实现上面的底部页签效果,示例代码如下:

@Entry @Component struct TabsExample {   @State currentIndex: number = 0;   private tabsController: TabsController = new TabsController();    @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() {     Tabs({ barPosition: BarPosition.End, controller: this.tabsController }) {       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')))     }     .barWidth('100%')     .barHeight(50)     .onChange((index: number) => {       this.currentIndex = index;     })   } }

示例代码中将barPosition的值设置为BarPosition.End,使页签显示在底部。使用@Builder修饰TabBuilder函数,生成由Image和Text组成的页签。同时也给Tabs组件设置了TabsController控制器,当点击某个页签时,调用changeIndex方法进行页签内容切换。

最后还需要给Tabs添加onChange事件,Tab页签切换后触发该事件,这样当我们左右滑动内容视图的时候,页签样式也会跟着改变。

管理组件状态

ArkUI作为一种声明式UI,具有状态驱动UI更新的特点。当用户进行界面交互或有外部事件引起状态改变时,状态的变化会触发组件自动更新。所以在ArkUI中,我们只需要通过一个变量来记录状态。当改变状态的时候,ArkUI就会自动更新界面中受影响的部分。

未完待续......

 

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!