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

news2024/12/28 20:20:48

一、引言

    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)
  }
}



 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

圈子论坛社交实名制系统---H5小程序APP,三端源码交付,允许二开!PHP系统uni书写!

圈子系统是一种社会化网络平台&#xff0c;它的核心是以用户为中心&#xff0c;围绕用户的兴趣、爱好、经历和职业等因素&#xff0c;将具有相同特质的个体聚集起来&#xff0c;形成具有共同话题和兴趣的社交圈子。这样的系统旨在帮助用户拓宽社交范围&#xff0c;提升社交效率…

Vue基知识六

一 vuex 1.1 简介 在Vue中实现集中式状态&#xff08;数据&#xff09;管理的一个Vue插件&#xff0c;对vue应用中多个组件的共享状态进行集中式的管理&#xff08;读/写&#xff09;&#xff0c;也是一种组件间通信的方式&#xff0c;且适用于任意组件间通信。 1.2 何时使用…

【代码】使用预训练的语义分割网络

P274书上的代码&#xff0c;这里是从ipynb文件中按顺序复制来的&#xff1a; 使用到的图片如下&#xff1a; 代码&#xff1a; import numpy as np import pandas as pd import matplotlib.pyplot as plt import PIL import torch from torchvision import transforms impor…

华为机考入门python3--(4)牛客4-字符串分隔

分类&#xff1a;字符串 知识点&#xff1a; 复制符号* 复制3个0 0*3 000 字符串截取 截取第i位到j-1位 str[i:j] 题目来自【牛客】 input_str input().strip()# 先补齐 if len(input_str) % 8 ! 0: input_str 0 * (8 - len(input_str) % 8) # 每8个分 out…

嵌入式软件工程师面试题——2025校招社招通用(C/C++)(四十四)

说明&#xff1a; 面试群&#xff0c;群号&#xff1a; 228447240面试题来源于网络书籍&#xff0c;公司题目以及博主原创或修改&#xff08;题目大部分来源于各种公司&#xff09;&#xff1b;文中很多题目&#xff0c;或许大家直接编译器写完&#xff0c;1分钟就出结果了。但…

win10通过ssh链接deepin23并开启x11转发

前提 主机环境&#xff1a;win10 lstc 虚拟机环境&#xff1a;deepin23beta2 终端&#xff1a;tabby x11服务器: vcxsrv 安装ssh sudo apt install ssh开启root登录(看你需求&#xff09; 首先你要给root账号设置密码 sudo passwd root修改配置文件 sudo vim /etc/ssh/ss…

源聚达科技:抖店的专营店怎么开

在数字化浪潮的推动下&#xff0c;抖音平台不仅为人们提供了丰富的娱乐内容&#xff0c;也成为了电商的新战场。不少创业者和品牌商纷纷选择在抖音上开设自己的专营店&#xff0c;以此抓住流量红利&#xff0c;拓宽销售渠道。那么&#xff0c;如何在抖音平台上成功开设一家专营…

Redis实现多种限流算法

一 常见限流算法 1 固定窗口限流 每一个时间段计数器&#xff0c;当计数器达到阈值后拒绝&#xff0c;每过完这个时间段&#xff0c;计数器重置0&#xff0c;重新计数。 优点&#xff1a;实现简单&#xff0c;性能高&#xff1b; 缺点&#xff1a;明显的临界问题&#xff0c…

PBM模型学习(五)UDF生长模型

DEFINE_PB_GROWTH_RATE(name, cell, thread, d_i) 该UDF在每个时间步开始时执行,只有在时间步开始时,颗粒粒径才会更新,同时才会UDF才会向文件写入数据GR单位是m/sC_PHASE DIAMETER(c,ts):返回颗粒粒径???,ts为颗粒相的线程C_VOF(cell,thread):颗粒相总体积C_PB DISCI(c…

在DevEco开发工具中,使用Previewer预览界面中的UI组件

1、在DevEco工具中&#xff0c;点击并展开PreViewer预览器 2、在PreViewer预览器中&#xff0c;点击Tt按钮&#xff08;Inspector&#xff09;切换至组件查看模式 3、在组件查看模式下选择组件&#xff0c;代码呈现选中状态&#xff0c;右侧呈现组件树&#xff0c;右下方呈现组…

FLStudio21.2.2国内中文版本怎么下载?

FL studio简称FL&#xff0c;全称&#xff1a;Fruity Loops Studio。在中国我们习惯叫它"水果"。它让你的计算机就像是全功能的音乐工作站&#xff0c;大混音盘&#xff0c;非常先进的制作工具&#xff0c;让你的音乐突破想象力的限制。 FL Studio主要功能 1、FL St…

Authorization Failed You can close this page and return to the IDE

一.问题描述 注册JetBrains成功&#xff0c;并且通过了学生认证&#xff0c;但在activate pycharm时&#xff0c;却显示Authorization Failed You can close this page and return to the IDE如上图 二.原因&#xff1a; 可能是因为之前使用了破解版pycharm 三.解决方法&am…

2024阿里云和腾讯云的第一战打响:搭建《幻兽帕鲁》私服游戏

为了搭建《幻兽帕鲁》游戏私服&#xff0c; 2024年阿里云 VS 腾讯云的第一场战争开始了…… 事情是这样的&#xff1a; 1月19日&#xff0c;最离谱新游 《幻兽帕鲁》突然爆火了&#xff0c;这是一款日本开发商展耗费4年开发的冒险类游戏&#xff0c;这款戏一推出就迅速俘获了…

KT6368A蓝牙芯片开发app小程序接口api里面的device ID是什么?

KT6368A蓝牙芯片开发app或者小程序的时候&#xff0c;给出的接口api&#xff0c;里面的device ID是什么&#xff1f; 有客户在开发app的过程中&#xff0c;问到我们device ID的问题 其实这个问题您稍微有点方法&#xff0c;直接百度搜搜就很清楚了&#xff0c;但是没办法&…

Linux 网络流量相关工具

本文聚焦于网络流量的查看、端口占用查看。至于网络设备的管理和配置&#xff0c;因为太过复杂且不同发行版有较大差异&#xff0c;这里就不赘述&#xff0c;后面看情况再写。 需要注意的是&#xff0c;这里列出的每一个工具都有丰富的功能&#xff0c;流量/端口信息查看只是其…

uniCloud发行部署H5进行网页托管

生成文件&#xff0c;生成文件这个和我们平时用uniapp 生成H5的时候是一样的&#xff0c;我们可以选择hash 或者history 模式&#xff0c;默认的这是显示的根目录&#xff0c;如果我们在根目录下建立了H5目录&#xff0c;那么我们在发布H5的时候&#xff0c;是需要在manifest.j…

vue3 codemirror关于 sql 和 json格式化的使用以及深入了解codemirror 使用json格式化提示错误的关键代码

文章目录 需求说明0、安装1. 导入js脚本2.配置3.html处使用4.js处理数据&#xff08;1&#xff09;json格式化处理&#xff08;2&#xff09;sql格式化处理 5. 解决问题1:json格式化错误提示报错&#xff08;1&#xff09;打开官网&#xff08;2&#xff09;打开官网&#xff0…

【css揭秘】

文章目录 背景与边框半透明边框多重边框box-shadowoutline 背景定位background-positionbackground-origincalc() 条纹背景水平条纹 形状圆形圆柱自适应的椭圆半椭圆四分之一椭圆 背景与边框 半透明边框 目标&#xff1a;给一个容器设置一层白色背景和一道半透明白色边框 写…

机器学习_集成学习之Bagging(集成多个模型,以降低整体的方差)

文章目录 Bagging 算法 —— 多个基模型的聚合决策树的聚合从树的聚合到随机森林从随机森林到极端随机森林 Bagging 算法 —— 多个基模型的聚合 Bagging 是我们要讲的第一种集成学习算法&#xff0c;是Bootstrap Aggregating 的缩写。有人把它翻译为套袋法、装袋法&#xff0…

Flutter App 生命周期观察监听

前言 本文主要讲解两种 Flutter生命周期观察监听 方式一&#xff1a;Flutter SDK 3.13 之前的方式&#xff0c;WidgetsBindingObserver&#xff1b; 方式二&#xff1a;Flutter SDK 3.13 开始的新方式&#xff0c;AppLifecycleListener&#xff1b; 测试平台&#xff1a;IO…