HarmonyOS鸿蒙学习基础篇 - 通用事件

一、引言

    HarmonyOS鸿蒙是华为推出的分布式操作系统,旨在为各种智能设备提供统一的操作系统。鸿蒙系统的一大特色是其强大的分布式能力,而通用事件则是实现这一能力的关键技术之一,本篇博客将介绍HarmonyOS鸿蒙中的通用事件。

二、 点击事件

点击事件又称单击事件,是我们平时操作过程中触发的最多的事件,是组件被点击时触发的事件。

名称

支持冒泡

功能描述

onClick(event: (event?: ClickEvent) => void)

点击动作触发该回调,event返回值见ClickEvent对象说明。

从API version 9开始,该接口支持在ArkTS卡片中使用。

ClickEvent对象说明

从API version 9开始,该接口支持在ArkTS卡片中使用。

名称

类型

描述

screenX

number

点击位置相对于应用窗口左上角的X坐标。

screenY

number

点击位置相对于应用窗口左上角的Y坐标。

x

number

点击位置相对于被点击元素左上角的X坐标。

y

number

点击位置相对于被点击元素左上角的Y坐标。

timestamp8+

number

事件时间戳。触发事件时距离系统启动的时间间隔,单位纳秒。

target8+

EventTarget

触发事件的元素对象显示区域。

source8+

SourceType

事件输入设备。

EventTarget8+对象说明

名称

参数类型

描述

area

Area

目标元素的区域信息。

三、触摸事件

 触摸事件是指在用户与触摸屏交互时发生的一系列事件

名称

是否冒泡

功能描述

onTouch(event: (event?: TouchEvent) => void)

手指触摸动作触发该回调,event返回值见TouchEvent介绍。

TouchEvent对象说明

名称

类型

描述

type

TouchType

触摸事件的类型。

touches

Array<TouchObject>

全部手指信息。

changedTouches

Array<TouchObject>

当前发生变化的手指信息。

stopPropagation

() => void

阻塞事件冒泡。

timestamp8+

number

事件时间戳。触发事件时距离系统启动的时间间隔,单位纳秒。

例如,当系统启动时间为2023/10/12 11:33, 在2023/10/12 11:34时触发触摸事件,时间戳返回的值为60,000,000,000ns。

target8+

EventTarget

触发事件的元素对象显示区域。

source8+

SourceType

事件输入设备。

TouchObject对象说明

名称

类型

描述

type

TouchType

触摸事件的类型。

id

number

手指唯一标识符。

screenX

number

触摸点相对于应用窗口左上角的X坐标。

screenY

number

触摸点相对于应用窗口左上角的Y坐标。

x

number

触摸点相对于被触摸元素左上角的X坐标。

y

number

触摸点相对于被触摸元素左上角的Y坐标。

示例
// 使用 @Entry 装饰器表示这个组件是整个应用的主入口  
// 使用 @Component 装饰器表示这个组件是 Flutter 应用的一部分  
@Entry  
@Component  
struct TouchExample {  
  // 定义一个名为 text 的状态变量,类型为 string,初始值为空字符串  
  @State  
  text: string = ''  
    
  // 定义一个名为 eventType 的状态变量,类型为 string,初始值为空字符串  
  @State  
  eventType: string = ''  
    
  // build 方法是一个特殊的方法,在 Flutter 中用于构建和渲染组件  
  build() {  
    // Column 是一个垂直布局容器,用于放置其他组件  
    Column() {  
      // 第一个 Button 组件,高度为 40,宽度为 100  
      Button('Touch').height(40).width(100)  
        // .onTouch 方法定义了当 Button 被触摸时触发的动作  
        .onTouch((event: TouchEvent) => {  
          // 根据触摸事件类型更新 eventType 状态变量  
          if (event.type === TouchType.Down) {  
            this.eventType = 'Down'  
          } else if (event.type === TouchType.Up) {  
            this.eventType = 'Up'  
          } else if (event.type === TouchType.Move) {  
            this.eventType = 'Move'  
          }  
          // 更新 text 状态变量,显示触摸事件的详细信息  
          this.text = 'TouchType:' + this.eventType + '\nDistance between touch point and touch element:\nx: '  
            + event.touches[0].x + '\n' + 'y: ' + event.touches[0].y + '\nComponent globalPos:('  
            + event.target.area.globalPosition.x + ',' + event.target.area.globalPosition.y + ')\nwidth:'  
            + event.target.area.width + '\nheight:' + event.target.area.height  
        })  
      // 第二个 Button 组件,高度为 50,宽度为 200,外边距为 20  
      Button('Touch').height(50).width(200).margin(20)  
        // 与第一个 Button 组件的触摸事件处理相同  
        .onTouch((event: TouchEvent) => {  
          if (event.type === TouchType.Down) {  
            this.eventType = 'Down'  
          } else if (event.type === TouchType.Up) {  
            this.eventType = 'Up'  
          } else if (event.type === TouchType.Move) {  
            this.eventType = 'Move'  
          }  
          this.text = 'TouchType:' + this.eventType + '\nDistance between touch point and touch element:\nx: '  
            + event.touches[0].x + '\n' + 'y: ' + event.touches[0].y + '\nComponent globalPos:('  
            + event.target.area.globalPosition.x + ',' + event.target.area.globalPosition.y + ')\nwidth:'  
            + event.target.area.width + '\nheight:' + event.target.area.height  
        })  
      // Text 组件显示 text 状态变量的值,即触摸事件的详细信息  
      Text(this.text)  
    // 设置 Column 的宽度为 '100%',设置内边距为 30(用于增加布局间距)  
    }.width('100%').padding(30)  
  } // build 方法结束,表示组件构建完成  
} // TouchExample 结构体定义结束

四、挂载卸载事件

     挂载卸载事件指组件从组件树上挂载、卸载时触发的事件。

事件

名称

支持冒泡

功能描述

onAppear(event: () => void)

组件挂载显示时触发此回调。

从API version 9开始,该接口支持在ArkTS卡片中使用。

onDisAppear(event: () => void)

组件卸载消失时触发此回调。

从API version 9开始,该接口支持在ArkTS卡片中使用。

示例 
// 导入ohos的promptAction模块,用于显示提示信息  
import promptAction from '@ohos.promptAction';  
  
// 使用@Entry装饰器表示这个组件是整个应用的主入口  
// 使用@Component装饰器表示这个组件是Flutter应用的一部分  
@Entry  
@Component  
struct AppearExample {  
  // 定义一个名为isShow的状态变量,类型为boolean,初始值为true  
  @State  
  isShow: boolean = true;  
    
  // 定义一个名为changeAppear的状态变量,类型为string,初始值为'点我卸载挂载组件'  
  @State  
  changeAppear: string = '点我卸载挂载组件';  
    
  // 定义一个私有变量myText,类型为string,初始值为'Text for onAppear'  
  private myText: string = 'Text for onAppear';  
    
  // build方法是一个特殊的方法,在Flutter中用于构建和渲染组件  
  build() {  
    // 创建一个Column垂直布局容器,用于放置其他组件  
    Column() {  
      // 创建一个Button组件,显示changeAppear变量的值  
      // 当点击这个按钮时,将触发onClick函数,切换isShow的值  
      Button(this.changeAppear)  
        .onClick(() => {  
          this.isShow = !this.isShow;  
        })  
        .margin(15); // 设置按钮的外边距为15  
      // 如果isShow为true,即显示下面的Text组件  
      if (this.isShow) {  
        // 创建一个Text组件,显示myText变量的值,字体大小为26,加粗  
        Text(this.myText).fontSize(26).fontWeight(FontWeight.Bold)  
          // 当这个Text组件首次显示时,触发onAppear函数,显示提示信息'The text is shown'  
          .onAppear(() => {  
            promptAction.showToast({  
              message: 'The text is shown',  
              duration: 2000 // 提示信息的显示时间为2000毫秒(2秒)  
            });  
          })  
          // 当这个Text组件被隐藏时,触发onDisAppear函数,显示提示信息'The text is hidden'  
          .onDisAppear(() => {  
            promptAction.showToast({  
              message: 'The text is hidden',  
              duration: 2000 // 提示信息的显示时间为2000毫秒(2秒)  
            });  
          });  
      } // if条件结束  
    } // Column组件结束  
    // 设置padding为30,设置宽度为100%,即占据整个屏幕宽度  
    .padding(30).width('100%');   
  } // build方法结束,表示组件构建完成  
} // AppearExample结构体定义结束

五、拖拽事件

   拖拽事件指组件被长按后拖拽时触发的事件。

事件

名称

支持冒泡

功能描述

onDragStart(event: (event?: DragEvent, extraParams?: string) => CustomBuilder | DragItemInfo)

第一次拖拽此事件绑定的组件时,触发回调。

- event:拖拽事件信息,包括拖拽点坐标。

- extraParams:拖拽事件额外信息,详见extraParams说明。

返回值:当前跟手效果所拖拽的对象,用于显示拖拽时的提示组件。

长按150ms可触发拖拽事件。优先级:长按手势配置时间小于等于150ms时,长按手势优先触发,否则拖拽事件优先触发。

onDragEnter(event: (event?: DragEvent, extraParams?: string) => void)

拖拽进入组件范围内时,触发回调。

- event:拖拽事件信息,包括拖拽点坐标。

- extraParams:拖拽事件额外信息,详见extraParams说明。

当监听了onDrop事件时,此事件才有效。

onDragMove(event: (event?: DragEvent, extraParams?: string) => void)

拖拽在组件范围内移动时,触发回调。

- event:拖拽事件信息,包括拖拽点坐标。

- extraParams:拖拽事件额外信息,详见extraParams说明。

当监听了onDrop事件时,此事件才有效。

onDragLeave(event: (event?: DragEvent, extraParams?: string) => void)

拖拽离开组件范围内时,触发回调。

- event:拖拽事件信息,包括拖拽点坐标。

- extraParams:拖拽事件额外信息,详见extraParams说明。

当监听了onDrop事件时,此事件才有效。

onDrop(event: (event?: DragEvent, extraParams?: string) => void)

绑定此事件的组件可作为拖拽释放目标,当在本组件范围内停止拖拽行为时,触发回调。

- event:拖拽事件信息,包括拖拽点坐标。

- extraParams:拖拽事件额外信息,详见extraParams说明。

DragItemInfo说明

名称

类型

必填

描述

pixelMap

PixelMap

设置拖拽过程中显示的图片。

builder

CustomBuilder

拖拽过程中显示自定义组件,如果设置了pixelMap,则忽略此值。

extraInfo

string

拖拽项的描述。

extraParams说明

用于返回组件在拖拽中需要用到的额外信息。

extraParams是Json对象转换的string字符串,可以通过Json.parse转换的Json对象获取如下属性。

名称

类型

描述

selectedIndex

number

当拖拽事件设在父容器的子元素时,selectedIndex表示当前被拖拽子元素是父容器第selectedIndex个子元素,selectedIndex从0开始。

仅在ListItem组件的拖拽事件中生效。

insertIndex

number

当前拖拽元素在List组件中放下时,insertIndex表示被拖拽元素插入该组件的第insertIndex个位置,insertIndex从0开始。

仅在List组件的拖拽事件中生效。

DragEvent说明

名称

类型

描述

getX()

number

当前拖拽点相对于屏幕左上角的x轴坐标,单位为vp。

getY()

number

当前拖拽点相对于屏幕左上角的y轴坐标,单位为vp。

示例
// xxx.ets
@Extend(Text) function textStyle () {
  .width('25%')
  .height(35)
  .fontSize(16)
  .textAlign(TextAlign.Center)
  .backgroundColor(0xAFEEEE)
}

@Entry
@Component
struct DragExample {
  @State numbers: string[] = ['one', 'two', 'three', 'four', 'five', 'six']
  @State text: string = ''
  @State bool: boolean = true
  @State eventType: string = ''
  @State appleVisible: Visibility = Visibility.Visible
  @State orangeVisible: Visibility = Visibility.Visible
  @State bananaVisible: Visibility = Visibility.Visible
  private dragList: string[] = ['apple', 'orange', 'banana']
  @State fruitVisible: Visibility[] = [Visibility.Visible, Visibility.Visible, Visibility.Visible]
  @State idx: number = 0

  // 自定义拖拽过程中显示的内容
  @Builder pixelMapBuilder() {
    Column() {
      Text(this.text)
        .width('50%')
        .height(60)
        .fontSize(16)
        .borderRadius(10)
        .textAlign(TextAlign.Center)
        .backgroundColor(Color.Yellow)
    }
  }

  build() {
    Column() {
      Text('There are three Text elements here')
        .fontSize(12)
        .fontColor(0xCCCCCC)
        .width('90%')
        .textAlign(TextAlign.Start)
        .margin(5)
      Row({ space: 15 }) {
        ForEach(this.dragList, (item, index) => {
          Text(item)
            .textStyle()
            .visibility(this.fruitVisible[index])
            .onDragStart(() => {
              this.bool = true
              this.text = item
              this.fruitVisible[index] = Visibility.None
              return this.pixelMapBuilder
            })
            .onTouch((event: TouchEvent) => {
              if (event.type === TouchType.Down) {
                this.eventType = 'Down'
                this.idx = index
              }
              if (event.type === TouchType.Up) {
                this.eventType = 'Up'
                if (this.bool) {
                  this.fruitVisible[index] = Visibility.Visible
                }
              }
            })
        })
      }.padding({ top: 10, bottom: 10 }).margin(10)

      Text('This is a List element')
        .fontSize(12)
        .fontColor(0xCCCCCC)
        .width('90%')
        .textAlign(TextAlign.Start)
        .margin(15)
      List({ space: 20 }) {
        ForEach(this.numbers, (item) => {
          ListItem() {
            Text(item)
              .width('100%')
              .height(80)
              .fontSize(16)
              .borderRadius(10)
              .textAlign(TextAlign.Center)
              .backgroundColor(0xAFEEEE)
          }
        }, item => item)
      }
      .editMode(true)
      .height('50%')
      .width('90%')
      .border({ width: 1 })
      .padding(15)
      .divider({ strokeWidth: 2, color: 0xFFFFFF, startMargin: 20, endMargin: 20 })
      .onDragEnter((event: DragEvent, extraParams: string) => {
        console.log('List onDragEnter, ' + extraParams + 'X:' + event.getX() + 'Y:' + event.getY())
      })
      .onDragMove((event: DragEvent, extraParams: string) => {
        console.log('List onDragMove, ' + extraParams + 'X:' + event.getX() + 'Y:' + event.getY())
      })
      .onDragLeave((event: DragEvent, extraParams: string) => {
        console.log('List onDragLeave, ' + extraParams + 'X:' + event.getX() + 'Y:' + event.getY())
      })
      .onDrop((event: DragEvent, extraParams: string) => {
        let jsonString = JSON.parse(extraParams);
        if (this.bool) {
          // 通过splice方法插入元素
          this.numbers.splice(jsonString.insertIndex, 0, this.text)
          this.bool = false
        }
        this.fruitVisible[this.idx] = Visibility.None
      })
    }.width('100%').height('100%').padding({ top: 20 }).margin({ top: 20 })
  }
}

六、按键事件

    按键事件指组件与键盘、遥控器等按键设备交互时触发的事件,适用于所有可获焦组件,例如Button。对于Text,Image等默认不可获焦的组件,可以设置focusable属性为true后使用按键事件。

事件

名称

支持冒泡

功能描述

onKeyEvent(event: (event?: KeyEvent) => void)

绑定该方法的组件获焦后,按键动作触发该回调,event返回值见KeyEvent介绍。

KeyEvent对象说明

名称

类型

描述

type

KeyType

按键的类型。

keyCode

number

按键的键码。

keyText

string

按键的键值。

keySource

KeySource

触发当前按键的输入设备类型。

deviceId

number

触发当前按键的输入设备ID。

metaKey

number

按键发生时元键(即Windows键盘的WIN键、Mac键盘的Command键)的状态,1表示按压态,0表示未按压态。

timestamp

number

事件时间戳。触发事件时距离系统启动的时间间隔,单位纳秒。

stopPropagation

() => void

阻塞事件冒泡传递。

 示例
@Entry  
@Component  
struct KeyEventExample {  
  // 定义一个名为text的状态变量,类型为string,初始值为空字符串  
  @State  
  text: string = '';  
    
  // 定义一个名为eventType的状态变量,类型为string,初始值为空字符串  
  @State  
  eventType: string = '';  
  
  // build方法是一个特殊的方法,在Flutter中用于构建和渲染组件  
  build() {  
    // 创建一个Column垂直布局容器,用于放置其他组件  
    Column() {  
      // 创建一个Button组件,显示文字“KeyEvent”  
      Button('KeyEvent')  
        // 当这个按钮接收到键盘事件时,触发onKeyEvent函数  
        .onKeyEvent((event: KeyEvent) => {  
          // 如果事件类型是按下(Down)  
          if (event.type === KeyType.Down) {  
            // 将eventType设置为'Down'  
            this.eventType = 'Down';  
          }  
          // 如果事件类型是释放(Up)  
          if (event.type === KeyType.Up) {  
            // 将eventType设置为'Up'  
            this.eventType = 'Up';  
          }  
          // 更新text的值,显示按键的类型、键码和键文  
          this.text = 'KeyType:' + this.eventType + '\nkeyCode:' + event.keyCode + '\nkeyText:' + event.keyText;  
        })  
      // 创建一个Text组件,显示text的值,并设置内边距为15像素  
      Text(this.text).padding(15)  
    // 设置Column的高度为300像素,宽度为100%,即全屏宽度,并设置外边距为35像素  
    }.height(300).width('100%').padding(35);   
  }    
}  

 七、焦点事件

 焦点事件指页面焦点在可获焦组件间移动时触发的事件,组件可使用焦点事件来处理相关逻辑。

  • 从API Version 8开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。

  • 目前仅支持通过外接键盘的tab键、方向键触发。

  • 存在默认交互逻辑的组件例如Button、TextInput等,默认即为可获焦,Text、Image等组件则默认状态为不可获焦,不可获焦状态下,无法触发焦点事件,需要设置focusable属性为true才可触发。

事件

名称支持冒泡功能描述
onFocus(event: () => void)当前组件获取焦点时触发的回调。
onBlur(event:() => void)当前组件失去焦点时触发的回调。
 示例
@Entry  
@Component  
struct FocusEventExample {  
  // 定义三个状态变量,分别表示三个按钮的颜色  
  @State  
  oneButtonColor: string = '#FFC0CB';  
    
  @State  
  twoButtonColor: string = '#87CEFA';  
    
  @State  
  threeButtonColor: string = '#90EE90';  
  
  build() {  
    // 创建一个Column垂直布局容器,并设置外边距为20像素  
    Column({ space: 20 }) {  
      // 创建一个名为“First Button”的按钮,设置背景颜色为oneButtonColor,宽度为260像素,高度为70像素,字体颜色为黑色,可获取焦点  
      Button('First Button')  
        .backgroundColor(this.oneButtonColor)  
        .width(260)  
        .height(70)  
        .fontColor(Color.Black)  
        .focusable(true)  
        // 当按钮获得焦点时,将oneButtonColor设置为红色  
        .onFocus(() => {  
          this.oneButtonColor = '#FF0000';  
        })  
        // 当按钮失去焦点时,将oneButtonColor设置回原来的颜色(#FFC0CB)  
        .onBlur(() => {  
          this.oneButtonColor = '#FFC0CB';  
        });  
      // 创建一个名为“Second Button”的按钮,设置背景颜色为twoButtonColor,宽度为260像素,高度为70像素,字体颜色为黑色,可获取焦点  
      Button('Second Button')  
        .backgroundColor(this.twoButtonColor)  
        .width(260)  
        .height(70)  
        .fontColor(Color.Black)  
        .focusable(true)  
        // 当按钮获得焦点时,将twoButtonColor设置为红色  
        .onFocus(() => {  
          this.twoButtonColor = '#FF0000';  
        })  
        // 当按钮失去焦点时,将twoButtonColor设置回原来的颜色(#87CEFA)  
        .onBlur(() => {  
          this.twoButtonColor = '#87CEFA';  
        });  
      // 创建一个名为“Third Button”的按钮,设置背景颜色为threeButtonColor,宽度为260像素,高度为70像素,字体颜色为黑色,可获取焦点  
      Button('Third Button')  
        .backgroundColor(this.threeButtonColor)  
        .width(260)  
        .height(70)  
        .fontColor(Color.Black)  
        .focusable(true)  
        // 当按钮获得焦点时,将threeButtonColor设置为红色  
        .onFocus(() => {  
          this.threeButtonColor = '#FF0000';  
        })  
        // 当按钮失去焦点时,将threeButtonColor设置回原来的颜色(#90EE90)  
        .onBlur(() => {  
          this.threeButtonColor = '#90EE90';  
        });  
    }  
  }  
}  

八、鼠标事件 

在鼠标的单个动作触发多个事件时,事件的顺序是固定的,鼠标事件默认透传。

  • 从API Version 8开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。
  • 目前仅支持通过外接鼠标触发。

事件

名称

支持冒泡

描述

onHover(event: (isHover?: boolean) => void)

鼠标进入或退出组件时触发该回调。

isHover:表示鼠标是否悬浮在组件上,鼠标进入时为true, 退出时为false。

onMouse(event: (event?: MouseEvent) => void)

当前组件被鼠标按键点击时或者鼠标在组件上悬浮移动时,触发该回调,event返回值包含触发事件时的时间戳、鼠标按键、动作、鼠标位置在整个屏幕上的坐标和相对于当前组件的坐标。

MouseEvent对象说明

名称

属性类型

描述

screenX

number

鼠标位置相对于应用窗口左上角的x轴坐标。

screenY

number

鼠标位置相对于应用窗口左上角的y轴坐标。

x

number

鼠标位置相对于当前组件左上角的x轴坐标。

y

number

鼠标位置相对于当前组件左上角的y轴坐标。

button

MouseButton

鼠标按键。

action

MouseAction

鼠标动作。

stopPropagation

() => void

阻塞事件冒泡。

timestamp8+

number

事件时间戳。触发事件时距离系统启动的时间间隔,单位纳秒。

target8+

EventTarget

触发事件的元素对象显示区域。

source8+

SourceType

事件输入设备。

示例 
@Entry
@Component
struct MouseEventExample {
  @State hoverText: string = 'no hover';
  @State mouseText: string = '';
  @State action: string = '';
  @State mouseBtn: string = '';
  @State color: Color = Color.Blue;

  build() {
    Column({ space: 20 }) {
      Button(this.hoverText)
        .width(180).height(80)
        .backgroundColor(this.color)
        .onHover((isHover: boolean) => {
          // 通过onHover事件动态修改按钮在是否有鼠标悬浮时的文本内容与背景颜色
          if (isHover) {
            this.hoverText = 'hover';
            this.color = Color.Pink;
          } else {
            this.hoverText = 'no hover';
            this.color = Color.Blue;
          }
        })
      Button('onMouse')
        .width(180).height(80)
        .onMouse((event: MouseEvent) => {
          switch (event.button) {
            case MouseButton.None:
              this.mouseBtn = 'None';
              break;
            case MouseButton.Left:
              this.mouseBtn = 'Left';
              break;
            case MouseButton.Right:
              this.mouseBtn = 'Right';
              break;
            case MouseButton.Back:
              this.mouseBtn = 'Back';
              break;
            case MouseButton.Forward:
              this.mouseBtn = 'Forward';
              break;
            case MouseButton.Middle:
              this.mouseBtn = 'Middle';
              break;
          }
          switch (event.action) {
            case MouseAction.Hover:
              this.action = 'Hover';
              break;
            case MouseAction.Press:
              this.action = 'Press';
              break;
            case MouseAction.Move:
              this.action = 'Move';
              break;
            case MouseAction.Release:
              this.action = 'Release';
              break;
          }
          this.mouseText = 'onMouse:\nButton = ' + this.mouseBtn +
          '\nAction = ' + this.action + '\nXY=(' + event.x + ',' + event.y + ')' +
          '\nscreenXY=(' + event.screenX + ',' + event.screenY + ')';
        })
      Text(this.mouseText)
    }.padding({ top: 30 }).width('100%')
  }
}

鼠标悬浮时改变文本内容与背景颜色: 

鼠标点击时:

九、组件区域变化事件 

组件区域变化事件指组件显示的尺寸、位置等发生变化时触发的事件。

事件

名称

支持冒泡

功能描述

onAreaChange(event: (oldValue: Area, newValue: Area) => void)

组件区域变化时触发该回调。仅会响应由布局变化所导致的组件大小、位置发生变化时的回调。由绘制变化所导致的渲染属性变化不会响应回调,如translate、offset。

- Area:返回目标元素的宽高以及目标元素相对父元素和页面左上角的坐标位置。

示例

@Entry  
@Component  
struct AreaExample {  
  // 定义一个状态变量value,初始值为'Text'  
  @State  
  value: string = 'Text';  
    
  // 定义一个状态变量sizeValue,初始值为空字符串  
  @State  
  sizeValue: string = '';  
  
  build() {  
    // 创建一个Column垂直布局容器  
    Column() {  
      // 创建一个Text组件,显示当前value的值,背景颜色为绿色,外边距为30像素,字体大小为20像素  
      Text(this.value)  
        .backgroundColor(Color.Green).margin(30).fontSize(20)  
        // 当Text组件被点击时,将value的值追加'Text'  
        .onClick(() => {  
          this.value = this.value + 'Text';  
        })  
        // 当Text组件的面积发生变化时,打印出变化前后的面积值到控制台,并将变化后的面积值赋给sizeValue  
        .onAreaChange((oldValue: Area, newValue: Area) => {  
          console.info(`Ace: on area change, oldValue is ${JSON.stringify(oldValue)} value is ${JSON.stringify(newValue)}`);  
          this.sizeValue = JSON.stringify(newValue);  
        });  
      // 创建一个新的Text组件,显示'new area is: '和sizeValue的值,外边距分别为30像素(右边)和30像素(左边)  
      Text('new area is: \n' + this.sizeValue).margin({ right: 30, left: 30 });  
    }  
  }  
}  

十、组件可见区域变化事件

组件可见区域变化事件是组件在屏幕中的显示区域面积变化时触发的事件,提供了判断组件是否完全或部分显示在屏幕中的能力,适用于广告曝光埋点之类的场景。

事件

名称

功能描述

onVisibleAreaChange(ratios: Array<number>, event: (isVisible: boolean, currentRatio: number) => void)

组件可见区域变化时触发该回调。

-ratios:阈值数组。其中,每个阈值代表组件可见面积(即组件在屏幕显示区的面积)与组件自身面积的比值。当组件可见面积与自身面积的比值大于或小于阈值时,均会触发该回调。每个阈值的取值范围为[0.0, 1.0],如果开发者设置的阈值超出该范围,则会实际取值0.0或1.0.

-isVisible:表示组件的可见面积与自身面积的比值是否大于阈值,true表示大于,false表示小于。

-currentRatio:触发回调时,组件可见面积与自身面积的比值。

说明:

该接口只适用于组件布局区域超出或离开了当前屏幕显示区域的情况,不支持组件堆叠(Stack)导致的面积不可见、使用offset或translate等图形变换接口导致的面积超出情况。

示例 
// xxx.ets
@Entry
@Component
struct ScrollExample {
  scroller: Scroller = new Scroller()
  private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  @State testTextStr: string = 'test'
  @State testRowStr: string = 'test'

  build() {
    Column() {
      Column() {
        Text(this.testTextStr)
          .fontSize(20)

        Text(this.testRowStr)
          .fontSize(20)
      }
      .height(100)
      .backgroundColor(Color.Gray)
      .opacity(0.3)

      Scroll(this.scroller) {
        Column() {
          Text("Test Text Visible Change")
            .fontSize(20)
            .height(200)
            .margin({ top: 50, bottom: 20 })
            .backgroundColor(Color.Green)
              // 通过设置ratios为[0.0, 1.0],实现当组件完全显示或完全消失在屏幕中时触发回调
            .onVisibleAreaChange([0.0, 1.0], (isVisible: boolean, currentRatio: number) => {
              console.info('Test Text isVisible: ' + isVisible + ', currentRatio:' + currentRatio)
              if (isVisible && currentRatio >= 1.0) {
                console.info('Test Text is fully visible. currentRatio:' + currentRatio)
                this.testTextStr = 'Test Text is fully visible'
              }

              if (!isVisible && currentRatio <= 0.0) {
                console.info('Test Text is completely invisible.')
                this.testTextStr = 'Test Text is completely invisible'
              }
            })

          Row() {
            Text('Test Row Visible  Change')
              .fontSize(20)
              .margin({ bottom: 20 })

          }
          .height(200)
          .backgroundColor(Color.Yellow)
          .onVisibleAreaChange([0.0, 1.0], (isVisible: boolean, currentRatio: number) => {
            console.info('Test Row isVisible:' + isVisible + ', currentRatio:' + currentRatio)
            if (isVisible && currentRatio >= 1.0) {
              console.info('Test Row is fully visible.')
              this.testRowStr = 'Test Row is fully visible'
            }

            if (!isVisible && currentRatio <= 0.0) {
              console.info('Test Row is is completely invisible.')
              this.testRowStr = 'Test Row is is completely invisible'
            }
          })

          ForEach(this.arr, (item) => {
            Text(item.toString())
              .width('90%')
              .height(150)
              .backgroundColor(0xFFFFFF)
              .borderRadius(15)
              .fontSize(16)
              .textAlign(TextAlign.Center)
              .margin({ top: 10 })
          }, item => item)

        }.width('100%')
      }
      .backgroundColor(0x317aff)
      .scrollable(ScrollDirection.Vertical)
      .scrollBar(BarState.On)
      .scrollBarColor(Color.Gray)
      .scrollBarWidth(10)
      .onScroll((xOffset: number, yOffset: number) => {
        console.info(xOffset + ' ' + yOffset)
      })
      .onScrollEdge((side: Edge) => {
        console.info('To the edge')
      })
      .onScrollEnd(() => {
        console.info('Scroll Stop')
      })

    }.width('100%').height('100%').backgroundColor(0xDCDCDC)
  }
}



 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/352355.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vue深入学习4—指令和生命周期

1.Vue是怎么识别 v- 指令的&#xff1f; 首先将HTML结构解析成属性列表&#xff0c;存入到数组中&#xff0c;接着遍历数组中的每一个节点&#xff0c;获取到不同指令对应的方法。 // 将HTML看作真正的属性列表 var ndoeAttrs node.attributes; var self this; // 类数组对象…

使用chrome爬取URL数据的实战代码

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

JavaScript 执行上下文与作用域

执行上下文与作用域 ​ 执行上下文的概念在 JavaScript 中是颇为重要的。变量或函数的上下文决定了它们可以访问哪些数据&#xff0c;以及它们的行为。每个上下文都有一个关联的变量对象&#xff08;variable object&#xff09;&#xff0c; 而这个上下文中定义的所有变量和函…

Java项目:17 基于SpringBoot的在线拍卖系统

作者主页&#xff1a;源码空间codegym 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 主要功能 前台登录&#xff1a; ①首页&#xff1a;轮播图、竞拍公告、拍卖商品展示 ②拍卖商品&#xff1a;分类&#xff1a;手机、数码、电器…

Vite学习指南

那本课程都适合哪些人群呢&#xff1f; 想要学习前端工程化&#xff0c;在新项目中投入使用 Vite 构建工具的朋友 Webpack 转战到 Vite 的小伙伴 前端架构师们&#xff0c;可以充实自己的工具箱 当然如果你没有项目相关开发经验&#xff0c;也可以从本课程中受益&#xff0…

【Linux】gcc中__builtin_expect的作用

本文首发于 慕雪的寒舍 引入 代码学习的时候&#xff0c;遇到了__builtin_expect这个之前从来没有遇到过的东西&#xff0c;网上搜了一下&#xff0c;发现纯C语言实现的GCD&#xff08;Grand Central Dispatch&#xff09;中就有定义过这个宏 #define _safe_cast_to_long(x) …

2017. 圆周排列

一、题目 Problem #2017 - ECNU Online Judge 二、思路 一开始以为是全排列&#xff0b;验证的问题&#xff0c;后来超时&#xff0c;然后转向组合排列思考&#xff0c;结果AC了 首先要知道&#xff1a;n个不同元素的圆排列有(n-1)!个 证明&#xff1a;将个n 元素中的某个元素…

语图奇缘:林浩然与杨凌芸的哲学漫画大冒险

语图奇缘&#xff1a;林浩然与杨凌芸的哲学漫画大冒险 Language Odyssey: The Philosophical Comic Adventure of Lin Haoran and Yang Lingyun 在一个充满逻辑谜题和言语陷阱的城市——逻言市&#xff0c;住着两位热衷于探索语言奥秘的年轻人&#xff0c;林浩然和杨凌芸。林浩…

docker之部署青龙面板

青龙面板是一个用于管理和监控 Linux 服务器的工具&#xff0c;具有定时运行脚本任务的功能。在实际情况下也可以用于一些定期自动签到等任务脚本的运行。 本次记录下简单的安装与使用&#xff0c;请提前安装好docker&#xff0c;参考之前的文章。 一、安装部署 1、拉取镜像 # …

黑马点评Redis项目实战(1)基于Session实现短信登录

一、导入黑马点评项目 1.后端部署 下载好资料之后&#xff0c;先在数据库中制作所需的表&#xff0c;如下&#xff1a; 接着在工程中按照自己的数据库设置相应的username和root&#xff0c;如下&#xff1a; 启动项目之后&#xff0c;输入网站&#xff1a;localhost:8081/sho…

【原神游戏开发日志3】登录和注册有何区别?

版权声明&#xff1a; ● 本文为“优梦创客”原创文章&#xff0c;您可以自由转载&#xff0c;但必须加入完整的版权声明 ● 文章内容不得删减、修改、演绎 ● 本文视频版本&#xff1a;见文末 ● 相关学习资源&#xff1a;见文末 前言 ● 这是我们原神游戏开发日记的第三期 ●…

【Java面试】Mysql

目录 sql的执行顺序索引的优点和缺点怎么避免索引失效(也属于sql优化的一种)一条sql查询非常慢&#xff0c;我们怎么去排查和优化&#xff1f;存储引擎 MylSAM和InnoDB、Memory的区别事务的四大特性(ACID)脏读、不可重复读、幻读事务的隔离级别&#xff1f;怎么优化数据库SQL优…

fastapi学习

fastapi框架 fastapi&#xff0c;一个用于构建 API 的现代、快速&#xff08;高性能&#xff09;的web框架。 fastapi是建立在Starlette和Pydantic基础上的&#xff0c;Pydantic是一个基于Python类型提示来定义数据验证、序列化和文档的库。Starlette是一种轻量级的ASGI框架/工…

春运倒计时,AR 引领铁路运输安全新风向

根据中国交通新闻网发布最新消息&#xff0c;今年春运全国跨区域人员流动量预计达 90 亿人次。 随着春运期间旅客数量不断创下新高&#xff0c;铁路运输面临着空前的挑战与压力。 图源&#xff1a;pixabay 聚焦铁路运输效率与旅客安全保障问题&#xff0c;本期行业趋势将探讨 …

在 Vue 项目中,可以通过设置不同的环境变量来区分不同的环境,例如本地开发环境、测试环境和生产环境。以下是设置环境变量的步骤:

1、在src下新建三个文件夹 &#xff08;.env.local、.env.test 和 .env.prod&#xff09; 2、配置信息 .env.local VUE_APP_ENVlocal VUE_APP_API_URLhttp://localhost:8080.env.test VUE_APP_ENVtest VUE_APP_API_URLhttp://124.220.110.203:9090/ .env.prod VUE_APP_…

看门狗定时器

1. 看门狗 看门狗: 用于设备在 程序异常(死机) 时 可以自动重启设备 实现原理: 通过定时器 进行定时 , 在定时器时间结束前 进行 "喂狗" 重置定时器时间 若时间到,还没有"喂狗",系统重启 本质就是一个定时器, 如何定时? 定时器 本质是对 晶振时钟进行 计…

上位机图像处理和嵌入式模块部署(c/c++ opencv)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 opencv可以运行在多个平台上面&#xff0c;当然windows平台也不意外。目前来说&#xff0c;opencv使用已经非常方便了&#xff0c;如果不想自己编译…

前端工程化之上cdn

一、cdn介绍 cdn的使用还是和前端打包相关&#xff0c;我们都希望前端最后的打包页面越小越好。那么可不可以把一些包不pack进去&#xff0c;让用户的流浪器自行下载呢&#xff1f;答案是可以的&#xff0c;那这些包就会被托管到分发站点上&#xff0c;就是在全国都有服务器&a…

【C++】STL和vector容器

STL和vector容器 基本概念六大组件容器算法迭代器容器算法迭代器 vector容器基本概念vector构造函数赋值vector的容量和大小vector插入与删除vector存取数据函数原型 vector互换容器vector预留空间vector容器嵌套容器 基本概念 长久以来&#xff0c;软件届一直希望建立一种可重…

解决 github.com port 443: Timed out 的问题

国内访问github.com总是那么不竟如人意&#xff0c;时而无法加载网页&#xff0c;时而等我们抽完了一根烟后&#xff0c;它还处于转圈的状态。 虽然国内有gitee.com等诸多的代码托管平台&#xff0c;但却鲜有国人愿意去呢&#xff1f;其中的缘由&#xff0c;想必也不用我多说&a…