首页 > 其他分享 >鸿蒙UI开发快速入门 —— part05:组件的样式复用

鸿蒙UI开发快速入门 —— part05:组件的样式复用

时间:2024-12-08 20:20:39浏览次数:8  
标签:Styles Extend 鸿蒙 Color Text part05 样式 UI 组件

1、 为什么要样式复用?

如果每个组件的样式都需要单独设置,在开发过程中会出现大量代码在进行重复样式设置,虽然可以复制粘贴,但为了代码简洁性和后续方便维护,样式的复用就很有必要了。

为此,鸿蒙推出了可以提炼公共样式进行复用的装饰器@Styles;

2、@Styles装饰器

@Styles装饰器可以将多条样式设置提炼成一个方法,直接在组件声明的位置调用。通过@Styles装饰器可以快速定义并复用自定义样式。用于快速定义并复用自定义样式。

有几点需要特别注意:

  • 目前@Styles仅支持通用属性和通用事件。

    什么是通用属性和通用事件?

通用属性指的是所有组件都具备的属性,例如:背景色、边框、宽高、圆角、字体等。通用事件指的是所有组件都具备的用户交互事件,例如:点击事件、焦点事件、长按事件等。

  • @Styles方法不支持参数,反例如下
// 反例:@Styles不支持参数
@Styles function globalFancy (value: number) {
  .width(value)
}

  • @Styles可以定义在组件内或全局,在全局定义时需在方法名前面添加function关键字,组件内定义时则不需要添加function关键字。
// 全局【只能在当前文件内使用,不支持export。】
@Styles function functionName() { ... }

// 在组件内
@Component
struct FancyUse {
  @Styles fancy() {
    .height(100)
  }
}

  • 定义在组件内的@Styles可以通过this访问组件的常量和状态变量,并可以在@Styles里通过事件来改变状态变量的值,示例如下:
@Component
struct FancyUse {
  @State heightValue: number = 100
  @Styles fancy() {
    .height(this.heightValue)
    .backgroundColor(Color.Yellow)
    .onClick(() => {
      this.heightValue = 200
    })
  }
}

  • 组件内@Styles的优先级高于全局@Styles。

    框架优先找当前组件内的@Styles,如果找不到,则会全局查找。

3、@Styles装饰器Demo

以下示例中演示了组件内@Styles和全局@Styles的用法。

// 定义在全局的@Styles封装的样式
@Styles function globalFancy  () {
  .width(150)
  .height(100)
  .backgroundColor(Color.Pink)
}

@Entry
@Component
struct FancyUse {
  @State heightValue: number = 100
  // 定义在组件内的@Styles封装的样式
  @Styles fancy() {
    .width(200)
    .height(this.heightValue)
    .backgroundColor(Color.Yellow)
    .onClick(() => {
      this.heightValue = 200
    })
  }

  build() {
    Column({ space: 10 }) {
      // 使用全局的@Styles封装的样式
      Text('FancyA')
        .globalFancy()
        .fontSize(30)
      // 使用组件内的@Styles封装的样式
      Text('FancyB')
        .fancy()
        .fontSize(30)
    }
  }
}

4、使用@Extend扩展已有组件样式

在实际开发中,我们可能会引用一些三方组件或者原生组件,同时,我们可能会针对这些三方组件做一些样式设置。此时,我们可以使用@Extend装饰器,它用于扩展已有组件样式。

使用方法很简单,代码示例如下:

@Extend(UIComponentName) function functionName { 
  // ... 
}

使用@Extend有几点需要注意:

  • 和@Styles不同,@Extend仅支持定义在全局,不支持在组件内部定义,而且只在定义的文件上下文中生效。

  • 和@Styles不同,@Extend支持封装指定组件的私有属性、私有事件和自身定义的全局方法,示例代码如下:

// @Extend(Text)可以支持Text的私有属性fontColor
@Extend(Text) function fancy () {
  .fontColor(Color.Red)
}
// superFancyText可以调用预定义的fancy
@Extend(Text) function superFancyText(size:number) {
    .fontSize(size)
    .fancy()
}

  • @Extend装饰的方法支持参数,开发者可以在调用时传递参数,调用遵循TS方法传值调用。
// xxx.ets
@Extend(Text) function fancy (fontSize: number) {
  .fontColor(Color.Red)
  .fontSize(fontSize)
}

@Entry
@Component
struct FancyUse {
  build() {
    Row({ space: 10 }) {
      Text('Fancy')
        .fancy(16)
      Text('Fancy')
        .fancy(24)
    }
  }
}

  • @Extend装饰的方法的参数可以为function,作为Event事件的句柄。
@Extend(Text) function makeMeClick(onClick: () => void) {
  .backgroundColor(Color.Blue)
  .onClick(onClick)
}

@Entry
@Component
struct FancyUse {
  @State label: string = 'Hello World';

  onClickHandler() {
    this.label = 'Hello ArkUI';
  }

  build() {
    Row({ space: 10 }) {
      Text(`${this.label}`)
        .makeMeClick(this.onClickHandler.bind(this))
    }
  }
}

  • @Extend的参数可以为状态变量,当状态变量改变时,UI可以正常的被刷新渲染。
@Extend(Text) function fancy (fontSize: number) {
  .fontColor(Color.Red)
  .fontSize(fontSize)
}

@Entry
@Component
struct FancyUse {
  @State fontSizeValue: number = 20
  build() {
    Row({ space: 10 }) {
      Text('Fancy')
        .fancy(this.fontSizeValue)
        .onClick(() => {
          this.fontSizeValue = 30
        })
    }
  }
}

5、@Extend装饰器Demo

以下示例声明了3个Text组件,每个Text组件均设置了fontStyle、fontWeight和backgroundColor样式【未使用样式复用】。

@Entry
@Component
struct FancyUse {
  @State label: string = 'Hello World'

  build() {
    Row({ space: 10 }) {
      Text(`${this.label}`)
        .fontStyle(FontStyle.Italic)
        .fontWeight(100)
        .backgroundColor(Color.Blue)
      Text(`${this.label}`)
        .fontStyle(FontStyle.Italic)
        .fontWeight(200)
        .backgroundColor(Color.Pink)
      Text(`${this.label}`)
        .fontStyle(FontStyle.Italic)
        .fontWeight(300)
        .backgroundColor(Color.Orange)
    }.margin('20%')
  }
}

我们尝试将公用的属性设置抽离,@Extend将样式组合复用,示例如下。

@Extend(Text) function fancyText(weightValue: number, color: Color) {
  .fontStyle(FontStyle.Italic)
  .fontWeight(weightValue)
  .backgroundColor(color)
}

@Entry
@Component
struct FancyUse {
  @State label: string = 'Hello World'

  build() {
    Row({ space: 10 }) {
      Text(`${this.label}`)
        .fancyText(100, Color.Blue)
      Text(`${this.label}`)
        .fancyText(200, Color.Pink)
      Text(`${this.label}`)
        .fancyText(300, Color.Orange)
    }.margin('20%')
  }
}

可以看到,之前重复的fontStyle、fontWeight、backgroundColor都被fancyText一个属性替换了。

6、One More Thing —— 多态样式

在实际开发中,我们一般会遇到这种情况,组件在不同的状态下,显示不同的样式,例如:默认是一个红色圆角按钮,按下后变成一个黑色按钮,示意图如下:

图片

此时,我们就需要用到“多态样式”了。

多态样式是属性方法,可以根据UI内部状态来设置样式,类似于css伪类,但语法不同。ArkUI提供以下四种状态:

  • focused:获焦态。

  • normal:正常态。

  • pressed:按压态。

  • disabled:不可用态。

Demo中动图展示了stateStyles最基本的使用场景。Button1处于第一个组件,Button2处于第二个组件。按压时显示为pressed态指定的黑色。使用Tab键走焦,先是Button1获焦并显示为focus态指定的粉色。当Button2获焦的时候,Button2显示为focus态指定的粉色,Button1失焦显示normal态指定的红色。代码如下:

@Entry
@Component
struct StateStylesSample {
  build() {
    Column() {
      Button('Button1')
        .stateStyles({
          focused: {
            .backgroundColor(Color.Pink)
          },
          pressed: {
            .backgroundColor(Color.Black)
          },
          normal: {
            .backgroundColor(Color.Red)
          }
        })
        .margin(20)
      Button('Button2')
        .stateStyles({
          focused: {
            .backgroundColor(Color.Pink)
          },
          pressed: {
            .backgroundColor(Color.Black)
          },
          normal: {
            .backgroundColor(Color.Red)
          }
        })
    }.margin('30%')
  }
}

7、结语

至此,我们将UI开发的组件样式相关的介绍完毕了。回顾一下,涉及到了

  • @Builder UI描述的概念以及如何添加UI组件;

  • UI和界面相关的的生命周期;

  • UI的逻辑复用和样式复用;

至此,我们已经可以编写一个静态页面了,但还不够,我们未来将继续学习状态管理和条件渲染。

有了状态管理和条件渲染,我们的界面就能随着用户的交互而发生变化。

下一个阶段,请持续关注:“鸿蒙UI开发快速入门 —— part06”

标签:Styles,Extend,鸿蒙,Color,Text,part05,样式,UI,组件
From: https://www.cnblogs.com/harmonyClassRoom/p/18593771

相关文章

  • How to Build and Deploy a Next.js App on Apache Server
    Step1:InstallingNext.jsnpminstall-gyarnmkdir-pv/var/www/project_folder_namecd/var/www/project_folder_nameyarncreatenext-appEditpackage.jsonandreplacethescriptsectionwiththefollowing:"scripts":{"dev":&quo......
  • GoPro Quik App for macOS will be end of life at the end of 2024 All In One
    GoProQuikAppformacOSwillbeendoflifeattheendof2024AllInOnemacOS版GoProQuikApp将于2024年底停用......
  • Build sandboxing disabled due to nsjail error
    如标题所示,这个是在编译AOSP的时候可能会遇到的警告。这个错有两种情况:在Ubuntu24.04上编译根据链接https://groups.google.com/g/android-building/c/DbDKuaIik3M所说,ubuntu24.04上的一些修改,会导致编译时遇到这个错误。临时解法是执行这个命令sudosysctl-wkernel.ap......
  • StringBuilder之GC优化原理
    在C#中,字符串(string)是不可变的(immutable),这意味着一旦创建了一个字符串对象,它的内容就不能被更改。任何对字符串的修改操作(如拼接、替换、截取等)都会生成一个新的字符串对象,而不是在原有字符串上进行修改。这种特性有几个重要的影响:不可变性带来的影响内存分配:每次对字符......
  • 渗透测试---burpsuite(5)web网页端抓包与APP渗透测试
    声明:学习素材来自b站up【泷羽Sec】,侵删,若阅读过程中有相关方面的不足,还请指正,本文只做相关技术分享,切莫从事违法等相关行为,本人与泷羽sec团队一律不承担一切后果视频地址:泷羽---bp(5)目录一、web网页端抓包 1.使用burpsuite内置浏览器进行抓包2.使用第三方浏览器进行抓......
  • AutoConsis:UI内容一致性智能检测4
    可参考美团技术团队1.背景目前,移动App上的业务页面愈发复杂,技术团队常会以页面为单位来拆解团队开发分工,同一类业务元素信息分散在不同团队负责的页面内。在具体的实践中,存在一类不易检出但又影响用户体验的异常:页面中的UI信息相互矛盾(如下图中同一个商品在多个页面上的实际......
  • BurpSuite工具-浏览器web页面的抓包
    一、证书的安装1.获取证书1.1.在Options功能导出证书1.2.浏览器下载证书2.将证书导入浏览器三、设置浏览器代理四、抓包成功结语burpsuite(5)web网页端抓包与app渗透测试_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1DTzSYfEeF?spm_id_from=333.788.videop......
  • Java基础之GUI:探索图形化界面编程的魅力
    一、引言Java的图形用户界面(GUI)编程为开发者提供了丰富的工具和组件,使得创建直观、交互性强的应用程序变得更加容易。本文将深入介绍Java基础中的GUI,包括其概念、组件、布局管理器以及事件处理等方面的知识。Java的图形用户界面(GUI)是一种通过图形化的方式与用户进行交......
  • 漏扫利器之Burpsuite概述(2)
    目录一、各功能点请求的主要组成1.请求行(RequestLine):2.Host头部(HostHeader):3.Cookie头部(CookieHeader):4.Cache-Control头部:5.Sec-Ch-Ua(用户代理客户端提示):6.Upgrade-Insecure-Requests头部:7.User-Agent头部:8.Accept头部:9.Sec-F......
  • AutoConsis:UI内容一致性智能检测15
    可参考美团技术团队1.背景目前,移动App上的业务页面愈发复杂,技术团队常会以页面为单位来拆解团队开发分工,同一类业务元素信息分散在不同团队负责的页面内。在具体的实践中,存在一类不易检出但又影响用户体验的异常:页面中的UI信息相互矛盾(如下图中同一个商品在多个页面上的实际......