【鸿蒙开发】第2课,Blank、Text、RichText和Marquee走马灯组件

144 阅读12分钟

1 Blank组件

Blank组件,顾名思义,是一个空白填充组件。在容器主轴方向上,Blank组件具有自动填充容器空余部分的能力。这一特性使得Blank组件在布局调整时显得尤为灵活和实用。值得注意的是,Blank组件仅在父组件为Row、Column或Flex时生效。

1.1 Blank组件的技术细节

接口与参数

  • 接口:Blank(min?: number | string)。从API version 10开始,Blank在父容器Row、Column、Flex主轴方向上未设置大小时会自动拉伸、压缩;设置了大小或容器自适应子节点大小时则不会自动拉伸、压缩。
  • 参数:除支持通用属性外,还支持color属性,用于设置空白填充的填充颜色。

行为特性

  • 当Blank组件在父容器主轴方向上未设置大小时,它会自动拉伸或压缩以填充空余部分。
  • 如果设置了大小或父容器自适应子节点大小,Blank组件则不会自动拉伸或压缩。
  • Blank设置主轴方向大小(size)与min时的约束关系为max(min, size)
  • 在父容器交叉轴上设置大小时,Blank组件不会撑满父容器交叉轴;交叉轴不设置大小时,alignSelf默认值为ItemAlign.Stretch,会撑满容器交叉轴。

1.2 Blank组件的应用场景

Blank组件在鸿蒙开发中具有广泛的应用场景,尤其是在需要自适应布局的场合。以下是一些典型的应用场景:

填充空白空间

  • 在Row、Column或Flex布局中,当子组件之间存在空白空间时,可以使用Blank组件进行填充,使布局更加紧凑和美观。

实现自适应布局

  • 通过调整Blank组件的大小和位置,可以实现不同屏幕尺寸和设备下的自适应布局,提升用户体验。

简化布局代码

  • 在某些复杂的布局中,使用Blank组件可以简化布局代码,提高开发效率。

1.3 示例代码

以下是一些使用Blank组件的示例代码,帮助开发者更好地理解其应用方法。

示例1:Blank组件在横竖屏占满空余空间效果

image.png

// xxx.ets
@Entry
@Component
struct BlankExample {
  build() {
    Column() {
      Row() {
        Text('Bluetooth').fontSize(18)
        Blank()
        Toggle({ type: ToggleType.Switch }).margin({ top: 14, bottom: 14, left: 6, right: 6 })
      }.width('100%').backgroundColor(0xFFFFFF).borderRadius(15).padding({ left: 12 })
    }.backgroundColor(0xEFEFEF).padding(20)
  }
}

示例2:Blank组件的父组件未设置宽度时,min参数的使用效果

image.png

// xxx.ets
@Entry
@Component
struct BlankExample {
  build() {
    Column({ space: 20 }) {
      // blank父组件不设置宽度时,Blank失效,可以通过设置min最小宽度填充固定宽度
      Row() {
        Text('Bluetooth').fontSize(18)
        Blank().color(Color.Yellow)
        Toggle({ type: ToggleType.Switch }).margin({ top: 14, bottom: 14, left: 6, right: 6 })
      }.backgroundColor(0xFFFFFF).borderRadius(15).padding({ left: 12 })
      Row() {
        Text('Bluetooth').fontSize(18)
        // 设置最小宽度为160
        Blank('160').color(Color.Yellow)
        Toggle({ type: ToggleType.Switch }).margin({ top: 14, bottom: 14, left: 6, right: 6 })
      }.backgroundColor(0xFFFFFF).borderRadius(15).padding({ left: 12 })
    }.backgroundColor(0xEFEFEF).padding(20).width('100%')
  }
}

2 Text组件

Text组件是鸿蒙UI框架中用于显示文本信息的组件。它支持多种字体、颜色、大小、对齐方式等属性,可以满足开发者在界面设计中对文本展示的各种需求。Text组件不仅适用于简单的文本提示,还可以用于展示复杂的文本内容,如长文本、多行文本、富文本等。

2.1 Text组件的技术细节

属性配置

  • text: 用于设置要显示的文本内容。可以是字符串类型,也可以是可解析为字符串的变量。
  • fontSize: 用于设置文本字体的大小。支持多种单位,如px(像素)、vp(视口比例单位)等。
  • fontColor: 用于设置文本的颜色。支持多种颜色表示方式,如十六进制颜色代码、RGBA等。
  • fontWeight: 用于设置文本的粗细。支持多种预定义值,如normalbold等。
  • textAlign: 用于设置文本的对齐方式。支持多种对齐方式,如leftcenterright等。
  • maxLines: 用于设置文本的最大行数。当文本内容超过指定行数时,可以通过设置overflow属性来控制文本的溢出行为。
  • textOverflow: 用于设置文本溢出时的处理方式。支持多种溢出处理方式,如clip(裁剪)、ellipsis(显示省略号)等。

样式定制

Text组件还支持通过CSS样式表或内联样式来定制文本的样式。开发者可以根据实际需求,为Text组件设置自定义的字体、颜色、阴影等样式,以实现更加丰富的文本展示效果。

性能优化

在处理大量文本内容时,Text组件的性能优化也是非常重要的。鸿蒙UI框架提供了一系列性能优化措施,如文本缓存、异步渲染等,以提高Text组件的渲染效率和响应速度。

2.2 Text组件的应用场景

Text组件在鸿蒙开发中有着广泛的应用场景,以下是一些典型的应用场景:

  1. 标题和标签

    Text组件可以用于显示应用的标题、标签、按钮文本等。通过合理配置字体大小、颜色和对齐方式等属性,可以使界面更加清晰易读。

  2. 长文本展示

    对于需要展示大量文本内容的场景,如新闻阅读、电子书阅读等,Text组件提供了多行文本和溢出处理的支持。开发者可以根据实际需求设置文本的最大行数和溢出处理方式,以实现良好的阅读体验。

2.3 实战示例

以下是一些使用Text组件的实战示例,帮助开发者更好地理解其应用方法。

示例1:基本文本展示

image.png

// xxx.ets
@Entry
@Component
struct TextExample {
  build() {
    Column() {
      Text('Hello, HarmonyOS!')
        .fontSize(24)
        .fontColor(Color.Blue)
        .fontWeight('bold')
        .textAlign(TextAlign.Center)
    }
  }
}

示例2:多行文本和溢出处理

image.png

// xxx.ets
@Entry
@Component
struct MultiLineTextExample {
  build() {
    Column() {
      Text('This is a long text content. It will be displayed in multiple lines if necessary. If the text content exceeds the maximum number of lines, it will be truncated according to the overflow setting.')
        .fontSize(16)
        .maxLines(3)
        .textOverflow({overflow: TextOverflow.Ellipsis})
    }
  }
}

3 RichText组件

RichText组件是鸿蒙开发框架(ArkUI)中的一个轻量级富文本显示组件,它支持HTML格式的文本解析与显示。这意味着,开发者可以通过HTML标记语言来定义文本的样式、布局和交互效果,而无需编写复杂的代码逻辑。RichText组件适用于加载与显示一段HTML字符串的场景,尤其适用于那些不需要对显示效果进行过多自定义的应用场景。

3.1 RichText组件的底层实现

RichText组件底层复用了Web组件来提供基础能力,包括但不限于HTML页面的解析、渲染等。这使得RichText组件能够高效地处理复杂的HTML内容,并呈现出与Web页面相似的展示效果。然而,这也带来了一定的限制,比如RichText组件不支持通过设置属性与事件来修改背景颜色、字体颜色、字体大小等样式,因为这些样式通常需要通过HTML或CSS来定义。

3.2 RichText组件的使用场景

由于RichText组件能够解析HTML格式的文本,因此它非常适用于那些需要展示复杂文本内容的应用场景。比如:

  • 即时通讯软件:用于显示聊天消息中的富文本内容,如加粗、斜体、下划线、表情等。
  • 新闻阅读应用:用于显示文章中的标题、段落、图片、链接等富文本元素。
  • 社交媒体应用:用于显示用户发布的动态、评论等富文本内容。

3.3 RichText组件的核心特性

  1. HTML解析能力:RichText组件能够解析HTML格式的文本,包括各种标签和属性,如<h1><p><a><img>等。
  2. 样式继承:RichText组件支持HTML中的样式继承机制,使得开发者可以通过CSS来定义全局样式或局部样式。
  3. 事件支持:RichText组件目前支持onStartonComplete两个事件,分别表示加载前和加载完成。这允许开发者在富文本内容加载的不同阶段执行特定的逻辑。
  4. 布局控制:RichText组件支持通过HTML和CSS来控制文本的布局,如行高、字间距、对齐方式等。

3.4 RichText组件的API接口

RichText组件的API接口相对简单,主要包括以下几个部分:

  • 构造函数RichText(content: string),接收一个HTML规范的字符串作为参数。
  • 事件接口
    • onStart(callback: () => void):加载前触发的事件回调。
    • onComplete(callback: () => void):加载完成后触发的事件回调。
  • 属性接口
    • width:设置组件的宽度。
    • height:设置组件的高度。
    • size:同时设置组件的宽度和高度。
    • layoutWeight:设置组件在布局中的权重。

3.5 RichText组件的注意事项

  1. 性能问题:RichText组件底层基于Web组件实现,因此比较消耗内存资源。在需要重复使用RichText组件的场景下(如在List组件中循环使用),可能会出现卡顿、滑动响应慢等现象。此时,建议考虑使用其他更轻量级的组件或优化布局。
  2. 内容限制:RichText组件不支持对HTML字符串的显示效果进行过多自定义。如果需要实现更复杂的富文本展示效果,可能需要考虑使用其他更强大的富文本处理库或自定义渲染逻辑。
  3. 视口默认值:移动设备的视口默认值大小为980px。如果RichText组件的宽度低于这个值,content内部的HTML则可能会产生一个可以滑动的页面被RichText组件包裹。如果想替换默认值,可以在content中添加<meta name="viewport" content="width=device-width">标签。

3.6 实战案例

以下是一个使用RichText组件的简单案例:

image.png

@Entry
@Component
struct RichTextDemo {
  @State data: string = '<h1 style="text-align: center;">这是标题</h1>' +
    '<p style="font-size: 64px; color: #333;">这是段落文本,支持HTML格式。</p>' +
    '<a href="#" style="font-size: 64px; color: blue; text-decoration: underline;">这是一个链接</a>';

  build() {
    Column() {
      RichText(this.data)
        .onStart(() => {
          console.info('RichText onStart');
        })
        .onComplete(() => {
          console.info('RichText onComplete');
        })
        .width('100%')
        .height(500)
        .backgroundColor(Color.White);
    }
  }
}

在这个案例中,我们定义了一个包含HTML格式的字符串,并将其传递给RichText组件进行显示。通过onStartonComplete事件回调,我们可以在富文本内容加载的不同阶段执行特定的逻辑。

4 Marquee组件

Marquee组件,即跑马灯组件,主要用于滚动展示一段单行文本。其独特之处在于,仅当文本内容宽度超过跑马灯组件宽度时,文本才会滚动显示。这一特性使得Marquee组件在需要展示较长文本且空间有限的情况下,成为一种非常有效的解决方案。

4.1 Marquee组件接口与参数

Marquee组件的接口定义如下:

Marquee(value: { 
    start: boolean, 
    step?: number, 
    loop?: number, 
    fromStart?: boolean, 
    src: string 
})

各参数的具体说明如下:

  • start:布尔类型,控制跑马灯是否进入播放状态。
  • step:数字类型(可选),滚动动画文本滚动步长。当step大于Marquee的文本宽度时,取默认值。
  • loop:数字类型(可选),设置重复滚动的次数。小于等于零时表示无限循环。在ArkTS卡片上,该参数设置任意值都仅在可见时滚动一次。
  • fromStart:布尔类型(可选),设置文本从头开始滚动或反向滚动。
  • src:字符串类型,需要滚动的文本内容。

4.2 Marquee组件属性

除了支持文本通用属性(如fontColor、fontSize、fontWeight、fontFamily)外,Marquee组件还支持以下属性:

  • allowScale:布尔类型,设置是否允许文本缩放。目前暂不支持该接口,默认值为false。

4.3 Marquee组件事件

Marquee组件除了通用事件外,还支持以下特定事件:

  • onStart:开始滚动时触发回调。从API version 9开始,该接口支持在ArkTS卡片中使用。
  • onBounce:完成一次滚动时触发。若循环次数不为1,则该事件会多次触发。从API version 9开始,该接口支持在ArkTS卡片中使用。
  • onFinish:滚动的全部循环次数完成时触发回调。从API version 9开始,该接口支持在ArkTS卡片中使用。

4.4 示例代码

以下是一个简单的示例代码,展示了如何在鸿蒙应用中使用Marquee组件:

动画.gif

// xxx.ets
@Entry
@Component
struct MarqueeExample {
    @State start: boolean = false
    private fromStart: boolean = true
    private step: number = 50
    private loop: number = Infinity
    private src: string = "Running Marquee starts rolling"

    build() {
    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
      Marquee({
        start: this.start,
        step: this.step,
        loop: this.loop,
        fromStart: this.fromStart,
        src: this.src
      })
        .width(360)
        .height(80)
        .fontColor('#FFFFFF')
        .fontSize(48)
        .fontWeight(700)
        .backgroundColor('#182431')
        .margin({ bottom: 40 })
        .onStart(() => {
          console.info('Marquee animation complete onStart')
        })
        .onBounce(() => {
          console.info('Marquee animation complete onBounce')
        })
        .onFinish(() => {
          console.info('Marquee animation complete onFinish')
        })
      Button(this.start ? 'Stop' : 'Start')
        .onClick(() => {
          this.start = !this.start
        })
        .width(120)
        .height(40)
        .fontSize(16)
        .fontWeight(500)
        .backgroundColor('#007DFF')
    }
    .width('100%')
    .height('100%')
  }
}