泉缘泉 发表于 2025-1-26 03:37:01

【HarmonyOS 5.0】第十三篇-ArkUI公共属性(二)

二、公共事件类属性

2.1.点击事件

组件被点击时触发的事件。
名称支持冒泡功能描述onClick(event: (event?: ClickEvent) => void)否点击动作触发该方法调用 ClickEvent对象阐明
属性名称类型描述screenXnumber点击点相对于设备屏幕左边沿的X坐标。screenYnumber点击点相对于设备屏幕上边沿的Y坐标。xnumber点击点相对于被点击元素左边沿的X坐标。ynumber点击点相对于被点击元素上边沿的Y坐标。target8+EventTarget被点击元素对象。timestamp8+number事件时间戳。source8+SourceType事件输入设备。 onClick:给组件添加点击事件的回调,设置回调后,当点击组件时会触发回调。回调参数 event 包含了点击信息,好比点击坐标等。
@Entry
@Component
struct OnclickExample {
build() {
    Column(){
      Text("click text")
      .width(120)
      .height(40)
      .backgroundColor("#00868B")//设置背景颜色
      .fontColor(Color.White)      //设置字体颜色
      .onClick(()=>{               //设置点击事件回调
          console.log("click text...........") //输出日志
      })
      .textAlign(TextAlign.Center)
    }
    .width("100%")
    .height("100%")
    .padding(30)
}
}
点击 Text 组件,控制台会打印 click text… 的日志。
2.2.触摸事件

onTouch:给组件设置触摸事件的回调,设置回调后,当手指在组件上按下、滑动、抬起时触发组件时会触发该回调。回调参数 event 包含了事件类型、点击坐标等信息。事件如下:
名称是否冒泡功能描述onTouch(event: (event?: TouchEvent) => void)是触摸动作触发该方法调用 参数类型TouchEvent对象阐明:
名称类型描述typeTouchType触摸事件的类型。touchesArray全部手指信息。changedTouchesArray当前发生变化的手指信息。stopPropagation() => void阻塞事件冒泡。timestamp8+number事件时间戳。target8+EventTarget触发手势事件的元素对象显示区域。source8+SourceType事件输入设备。 预览结果如下:
@Entry
@Component
struct OntouchExample {
build() {
    Column(){
      Text("click text")
      .width(120)
      .height(40)
      .textAlign(TextAlign.Center)
      .backgroundColor("#00868B")//设置背景颜色
      .fontColor(Color.White)      //设置字体颜色
      .onTouch((event)=>{ //设置触摸事件回调
          if(event.type == TouchType.Down){ //手指按下的事件回调
            console.log("touch down");
          }else if(event.type == TouchType.Move){//手指移动的事件回调
            console.log("touch move");
          }else if(event.type == TouchType.Cancel){ //触摸事件取消时的事件回调
            console.log("touch cancel");
          }else if(event.type == TouchType.Up){ //手指抬起的事件回调
            console.log("touch up");
          }
      })
    }
    .width("100%")
    .height("100%")
    .padding(30)
}
}
触摸该Text 组件,控制台输出如下:
12-25 10:16:30.427 I A0c0d0/JSApp: app Log: touch down
12-25 10:16:30.533 I A0c0d0/JSApp: app Log: touch up
12-25 10:16:32.270 I A0c0d0/JSApp: app Log: touch down
12-25 10:16:32.868 I A0c0d0/JSApp: app Log: touch move
使用触摸事件实现的通用下拉刷新和上拉加载更多的 RefreshLayout 组件,如下所示:
2.3.拖拽事件

拖拽事件指组件被长按后拖拽时触发的事件。给组件设置拖拽事件的回调,设置回调后,拖拽组件动作发生时会触发相应的拖拽回调,各拖拽方法阐明如下:


[*]onDragStart:第一次拖拽此事件绑定的组件时,触发回调。参数 event 包含了拖拽坐标等信息,extraParams 拖拽事件的额外信息。拖拽事件留意事项:

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

[*]onDragEnter:拖拽进入组件范围内时,触发回调。参数 event 包含了拖拽坐标等信息,extraParams 拖拽事件的额外信息。拖拽事件留意事项:

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

[*]onDragMove:拖拽在组件范围内移动时,触发回调。参数 event 包含了拖拽坐标等信息,extraParams 拖拽事件的额外信息。拖拽事件留意事项:

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

[*]onDragLeave:拖拽离开组件范围内时,触发回调。参数 event 包含了拖拽坐标等信息,extraParams 拖拽事件的额外信息。拖拽事件留意事项:

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

[*]onDrop:绑定此事件的组件可作为拖拽释放目标,当在本组件范围内停止拖拽行为时,触发回调。参数 event 包含了拖拽坐标等信息,extraParams 拖拽事件的额外信息。
留意上面会用到罗列:Visibility
名称描述Hidden隐藏,但参与结构举行占位。Visible显示。None隐藏,但不参与结构,不举行占位。 案例代码如下:
// xxx.ets
// 定义文本样式函数
@Extend(Text) function textStyle() {
.width('25%')// 设置宽度为25%
.height(35)// 设置高度为35
.fontSize(16)// 设置字体大小为16
.textAlign(TextAlign.Center)// 设置文本居中对齐
.backgroundColor(0xAFEEEE)// 设置背景颜色为浅蓝色
}

// 定义组件
@Entry
@Component
struct Index {
// 定义状态变量
@State numbers: string[] = ['1', '2', '3', '4', '5', '6']// 定义字符串数组变量
@State text: string = ''// 定义字符串变量
@State bool: boolean = true// 定义布尔变量
@State eventType: string = ''// 定义字符串变量
/**
   * Visibility.Visible 隐藏,但参与布局进行占位。
   * 隐藏,但不参与布局,不进行占位。
   */
@State fruitVisible: Visibility[] = // 定义可见性枚举数组变量
@State idx: number = 0// 定义数字变量

// 自定义拖拽过程中显示的内容
@Builder pixelMapBuilder() {
    Column() {
      Text(this.text)
      .width('50%')// 设置宽度为50%
      .height(60)// 设置高度为60
      .fontSize(16)// 设置字体大小为16
      .borderRadius(10)// 设置边框圆角半径为10
      .textAlign(TextAlign.Center)// 设置文本居中对齐
      .backgroundColor(Color.Yellow)// 设置背景颜色为黄色
    }
}

//自定义拖拽的文本框
@Builder dragText(textContent:string, index:number){
    Text(textContent)// 在文本框中显示传入的文本内容
      .textStyle() // 使用自定义的文本样式
      .visibility(this.fruitVisible) // 设置文本框的可见性为预先定义的数组中对应索引的值
      .onDragStart(() => {// 当开始拖拽时触发以下操作
      this.bool = true// 将布尔变量设置为true
      this.text = textContent// 将文本内容赋值给this.text
      this.fruitVisible = Visibility.None// 将预先定义的数组中对应索引的值设置为不可见
      return this.pixelMapBuilder // 返回自定义拖拽过程中显示的内容
      })
      .onTouch((event: TouchEvent) => {// 当触摸事件发生时触发以下操作
      if (event.type === TouchType.Down) {// 如果触摸类型为按下
          this.eventType = 'Down'// 将事件类型设置为“Down”
          this.idx = index// 将当前索引赋值给this.idx
      }
      if (event.type === TouchType.Up) {// 如果触摸类型为抬起
          this.eventType = 'Up'// 将事件类型设置为“Up”
          if (this.bool) {// 如果布尔变量为true
            this.fruitVisible = Visibility.Visible// 将预先定义的数组中对应索引的值设置为可见
          }
      }
      })
}

// 构建组件
build() {
    Column() {
      // 显示说明文本
      Text('准备三个拖拽的元素')
      .fontSize(12)// 设置字体大小为12
      .fontColor(0xCCCCCC)// 设置字体颜色为灰色
      .width('90%')// 设置宽度为90%
      .textAlign(TextAlign.Start)// 设置文本左对齐
      .margin(5)// 设置外边距为5
      // 显示水果文本元素
      Row({ space: 15 }) {
      //调用组件产生文本框, 数组是上面元素是否可见的索引列表
      this.dragText("apple", 0)
      this.dragText("orange", 1)
      this.dragText("banana", 2)

      }.padding({ top: 10, bottom: 10 }).margin(10)

      // 显示列表元素
      Text('拖入后的元素列表')
      .fontSize(12)// 设置字体大小为12
      .fontColor(0xCCCCCC)// 设置字体颜色为灰色
      .width('90%')// 设置宽度为90%
      .textAlign(TextAlign.Start)// 设置文本左对齐
      .margin(15)// 设置外边距为15
      List({ space: 20 }) {
      ForEach(this.numbers, (item) => {
          ListItem() {
            Text(item)
            .width('100%')// 设置宽度为100%
            .height(80)// 设置高度为80
            .fontSize(16)// 设置字体大小为16
            .borderRadius(10)// 设置边框圆角半径为10
            .textAlign(TextAlign.Center)// 设置文本居中对齐
            .backgroundColor(0xAFEEEE)// 设置背景颜色为浅蓝色
          }
      }, item => item)
      }
      .editMode(true)// 设置编辑模式为true
      .height('50%')// 设置高度为50%
      .width('90%')// 设置宽度为90%
      .border({ width: 1 })// 设置边框宽度为1
      .padding(15)// 设置内边距为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);// 将额外参数解析为JSON格式并赋值给jsonString
      if (this.bool) {// 如果布尔变量为true
          // 通过splice方法插入元素
          this.numbers.splice(jsonString.insertIndex, 0, this.text)// 在numbers数组中的指定位置插入this.text
          this.bool = false// 将布尔变量设置为false
      }
      this.fruitVisible = Visibility.None// 将预先定义的数组中对应索引的值设置为不可见
      })
    }.width('100%').height('100%').padding({ top: 20 }).margin({ top: 20 })
}
}
预览结果如下:
https://i-blog.csdnimg.cn/img_convert/593bfde8b11afd73edbef0cbba70543a.gif
2.4.挂载卸载事件

挂载卸载事件指组件从组件树上挂载、卸载时触发的事件。各 API 方法阐明如下:


[*]onAppear:组件从组件树上挂载时的回调。
[*]onDisAppear:组件从组件树上卸载时的回到。
案例代码如下:
import promptAction from '@ohos.promptAction'// 导入名为promptAction的模块

@Entry// 声明为入口组件
@Component// 声明为组件
struct AppearExample {// 定义名为AppearExample的结构体
@State isShow: boolean = false// 声明一个名为isShow的状态变量,初始值为false

build() {// 定义一个名为build的方法
    Column() {// 创建一个Column组件

      Button(this.isShow?"卸载":"挂载")// 创建一个Button组件,并根据isShow的值显示不同的文本内容
      .onClick(() => {// 绑定点击事件处理函数
          this.isShow = !this.isShow// 切换isShow的值
      }).margin(15)// 设置按钮的外边距为15

      Column(){// 创建一个嵌套的Column组件
      if(this.isShow){// 如果isShow为true
          Text("挂载/卸载")// 创建一个Text组件,显示文本'挂载/卸载'
            .fontSize(22)// 设置字体大小为22
            .onAppear(()=>{// 绑定onAppear事件处理函数
            console.log("------------------实现了挂载------------------")// 在控制台输出信息
            promptAction.showToast({// 调用promptAction模块的showToast方法
                message: 'The text is shown',// 设置提示消息为'The text is shown'
                duration: 2000// 设置提示持续时间为2000毫秒
            })
            })
            .onDisAppear(()=>{// 绑定onDisAppear事件处理函数
            console.log("------------------实现了卸载------------------")// 在控制台输出信息
            promptAction.showToast({// 调用promptAction模块的showToast方法
                message: 'The text is hidden',// 设置提示消息为'The text is hidden'
                duration: 2000// 设置提示持续时间为2000毫秒
            })
            })
      }
      }
    }.padding(30).width('100%')// 设置Column组件的内边距为30,宽度为100%
}
}
预览结果如下:
https://i-blog.csdnimg.cn/img_convert/da79dd102f291f23619817435b9050d6.gif
2.5.焦点事件

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


[*]目前仅支持通过外接键盘的tab键、方向键触发。
[*]存在默认交互逻辑的组件比方Button、TextInput等,默认即为可获焦,Text、Image等组件则默认状态为不可获焦,不可获焦状态下,无法触发焦点事件,必要设置focusable属性为true才可触发。
组件获取到焦点或者失去焦点时的事件回调,组件可使用焦点事件来更改内容。阐明如下:


[*]onFocus:组件获取到焦点时的事件回调。
[*]onBlur:组件失去焦点时的事件回调。
案例代码如下:
@Entry
@Component
struct FocusEventExample {
@State oneButtonColor: string = '#FFC0CB'
@State twoButtonColor: string = '#87CEFA'
@State threeButtonColor: string = '#90EE90'

build() {
    Column({ space: 20 }) {
      // 通过外接键盘的上下键可以让焦点在三个按钮间移动,按钮获焦时颜色变化,失焦时变回原背景色

      Button("First Button")
      .backgroundColor(this.oneButtonColor)
      .width(260)
      .height(80)
      .fontColor(Color.Black)
      .focusable(true)// 设置可获取焦点
      //当前组件获取焦点时触发的回调
      .onFocus(()=>{
          this.oneButtonColor = "#FF0000"
      })
      //当前组件失去焦点时触发的回调。
      .onBlur(()=>{
          this.oneButtonColor = "#FFC0CB"
      })

      Button("Second Button")
      .backgroundColor(this.twoButtonColor)
      .width(260)
      .height(80)
      .fontColor(Color.Black)
      .focusable(true)// 设置可获取焦点
          //当前组件获取焦点时触发的回调
      .onFocus(()=>{
          this.twoButtonColor = "#00688B"
      })
          //当前组件失去焦点时触发的回调。
      .onBlur(()=>{
          this.twoButtonColor = "#90EE90"
      })

      Button("Third Button")
      .backgroundColor(this.threeButtonColor)
      .width(260)
      .height(80)
      .fontColor(Color.Black)
      .focusable(true)// 设置可获取焦点
          //当前组件获取焦点时触发的回调
      .onFocus(()=>{
          this.threeButtonColor = "#9B30FF"
      })
          //当前组件失去焦点时触发的回调。
      .onBlur(()=>{
          this.threeButtonColor = "#AEEEEE"
      })

    }.width('100%').margin({ top: 20 })
}
}
点击后,用外接键盘上下键移动,模拟获取和失去焦点后改变不同的配景颜色,预览结果如下:
https://i-blog.csdnimg.cn/img_convert/bdf8b2b31b40a02e6c191c0c84b5fcf8.gif
2.6.区域变化事件

事件定义如下:
declare class CommonMethod<T> {
// 区域变化的事件回调
onAreaChange(event: (oldArea: Area, newArea: Area) => void): T;
}
//Area返回的数据类型说明
declare interface Area {
width: Length;            // 组件的宽度,单位为vp。
height: Length;         // 组件的高度,单位为vp。
position: Position;       // 组件左上角相对父组件左上角的位置。
globalPosition: Position; // 组件左上角相对页面左上角的位置。
}
组件区域发生变化会触发该回调,好比组件尺寸或者在屏幕上的位置发生改变都会触发该回调。


[*]oldArea:组件变化前区域信息。
[*]newArea:组件变化后区域信息。
预览代码如下:
//定义一个全局样式
@Styles function btnGlobalPressedStyle(){// 定义名为btnGlobalPressedStyle的全局样式函数
.backgroundColor("#3CB371")// 设置背景颜色为"#3CB371"
.width(180)// 设置宽度为180
.height(50)// 设置高度为50
}
//定义一个全局样式
@Styles function btnGlobalNormalStyle(){// 定义名为btnGlobalNormalStyle的全局样式函数
.backgroundColor("#CD5555")// 设置背景颜色为"#CD5555"
.width(180)// 设置宽度为180
.height(50)// 设置高度为50
}

@Entry// 声明为入口组件
@Component// 声明为组件
struct AreaExample{// 定义名为AreaExample的结构体
@State text: string = "";// 声明一个名为text的状态变量,初始值为空字符串
@State area: string = "";// 声明一个名为area的状态变量,初始值为空字符串

build() {// 定义一个名为build的方法
    Column({space:20}){// 创建一个Column组件,设置间距为20
      Button("Chang Area")// 创建一个Button组件,显示文本"Chang Area"
      .stateStyles({// 设置状态样式
          normal:btnGlobalPressedStyle,// 普通状态使用btnGlobalPressedStyle样式
          pressed:btnGlobalNormalStyle// 按下状态使用btnGlobalNormalStyle样式
      })
      .onClick((event: ClickEvent) => {// 绑定点击事件处理函数
          this.text += "Modifications";// 在text变量后追加字符串"Modifications"
      })

      Text(this.text)// 创建一个Text组件,显示text变量的值
      .fontSize(18)// 设置字体大小为18
          //当该组件的大小或位置改变完成时,会触发该回调。
          //返回目标元素的宽高以及目标元素相对父元素和页面左上角的坐标位置。
      .onAreaChange((oldArea, newArea)=>{// 绑定onAreaChange事件处理函数
          this.area = "old:\n" + JSON.stringify(oldArea) + "\n\n\nnew:\n" + JSON.stringify(newArea);// 设置area变量的值为旧区域和新区域的JSON字符串
      })

      Text(this.area).fontSize(18)// 创建一个Text组件,显示area变量的值,设置字体大小为18

    }.width("100%").height("100%").padding(10)// 设置Column组件的宽度、高度和内边距
}
}
上面的代码点击一次,就会给拼接一段文本,这有文本元素大小就会改变,这时候就会触发onAreaChange的实验,预览结果如下:
https://i-blog.csdnimg.cn/img_convert/0cb34779b32be7478039c7eb2d1b84c9.gif
三、公共剪切类属性

ArkUI框架提供的组件继承自 CommonMethod ,因此在 CommonMethod 中的定义的属性是组件的公共属性,用于对组件举行裁剪、遮罩处理。属性
名称参数类型默认值描述clipCircle | Ellipse | Path | Rect | booleanfalse参数为相应类型的组件,按指定的形状对当前组件举行裁剪;参数为boolean类型时,设置是否按照边缘表面举行裁剪。maskCircle | Ellipse | Path | Rect-在当前组件上加上指定形状的遮罩。 3.1.遮罩设置

mask:给当前组件添加指定形状的遮罩,遮罩的参考系为当前组件的左上角坐标,为了使遮罩显示还必须调用 fill() 方法添加遮罩颜色。参数阐明如下:


[*]Circle:添加圆形遮罩,案比方下:
@Entry
@Component
struct CirleExample {
build() {
    Column({space:20}){
      Image($r("app.media.Snip")) //默认加载图片
      .width(160)
      .height(90)

      Image($r("app.media.Snip")) //居左剪切出来一个圆形
      .width(160)
      .height(90)
          //Circle用于绘制圆形的组件:以90为直径, fill设置填充区域颜色。
      .mask(new Circle({width:90, height:90}).fill(Color.Pink))

      Image($r("app.media.Snip")) //居中裁剪出图片
      .width(160)
      .height(90)
      //Circle用于绘制圆形的组件,如果宽和高不一致,则按照较小值为:直径
      .mask(new Circle({width:160, height:90}).fill(Color.Pink))

      Image($r("app.media.Snip")) //居右裁剪出图片
      .width(160)
      .height(90)
      //以90为直径
      .mask(new Circle({width:230, height:90}).fill(Color.Pink))

    }
    .width("100%").height("100%").padding({top:20, bottom:20})
}
}
预览结果如下:
https://i-blog.csdnimg.cn/img_convert/0c39cfdb1f17229befc6726e59521bcb.png


[*]Ellipse:添加椭圆形遮罩,样比方下:
@Entry
@Component
struct EllipseExample {
build() {
    Column({space:20}){
      Image($r("app.media.Snip")) //默认加载图片
      .width(160)
      .height(90)

      Image($r("app.media.Snip")) //居左剪切出来一个圆形
      .width(160)
      .height(90)
          //Ellipse用于绘制椭圆的组件:如果宽和高一致,则为圆形, fill设置填充区域颜色。
      .mask(new Ellipse({width:90, height:90}).fill(Color.Pink))

      Image($r("app.media.Snip")) //居中裁剪出图片
      .width(160)
      .height(90)
      //Ellipse用于绘制椭圆的组件,
      .mask(new Ellipse({width:160, height:90}).fill(Color.Pink))

    }
    .width("100%").height("100%").padding({top:20, bottom:20})
}
}
预览结果如下:
https://i-blog.csdnimg.cn/img_convert/c37cfe1363841371f94faa9f92d2748e.png


[*]Path:在指定路径上添加遮罩, Path 使用 commands 才生结果,
路径绘制的下令字符串,单元为px。commands支持的绘制下令如下:
commands支持的绘制下令如下:
下令名称参数阐明Mmoveto(x y)在给定的 (x, y) 坐标处开始一个新的子路径。比方,M 0 0 表示将(0, 0)点作为新子路径的起始点。Llineto(x y)从当前点到给定的 (x, y) 坐标画一条线,该坐标成为新的当前点。比方,L 50 50 表示绘制当前点到(50, 50)点的直线,并将(50, 50)点作为新子路径的起始点。Hhorizontal linetox从当前点绘制一条程度线,等效于将y坐标指定为0的L下令。比方,H 50 表示绘制当前点到(50, 0)点的直线,并将(50, 0)点作为新子路径的起始点。Vvertical linetoy从当前点绘制一条垂直线,等效于将x坐标指定为0的L下令。比方,V 50 表示绘制当前点到(0, 50)点的直线,并将(0, 50)点作为新子路径的起始点。Ccurveto(x1 y1 x2 y2 x y)使用 (x1, y1) 作为曲线起点的控制点, (x2, y2) 作为曲线终点的控制点,从当前点到 (x, y) 绘制三次贝塞尔曲线。比方,C100 100 250 100 250 200 表示绘制当前点到(250, 200)点的三次贝塞尔曲线,并将(250, 200)点作为新子路径的起始点。Ssmooth curveto(x2 y2 x y)(x2, y2) 作为曲线终点的控制点,绘制从当前点到 (x, y) 绘制三次贝塞尔曲线。若前一个下令是C或S,则起点控制点是上一个下令的终点控制点相对于起点的映射。 比方,C100 100 250 100 250 200 S400 300 400 200第二段贝塞尔曲线的起点控制点为(250, 300)。假如没有前一个下令或者前一个下令不是 C或S,则第一个控制点与当前点重合。Qquadratic Belzier curve(x1 y1 x y)使用 (x1, y1) 作为控制点,从当前点到 (x, y) 绘制二次贝塞尔曲线。比方,Q400 50 600 300 表示绘制当前点到(600, 300)点的二次贝塞尔曲线,并将(600, 300)点作为新子路径的起始点。Tsmooth quadratic Belzier curveto(x y)绘制从当前点到 (x, y) 绘制二次贝塞尔曲线。若前一个下令是Q或T,则控制点是上一个下令的终点控制点相对于起点的映射。 比方,Q400 50 600 300 T1000 300第二段贝塞尔曲线的控制点为(800, 350)。 假如没有前一个下令或者前一个下令不是 Q或T,则第一个控制点与当前点重合。Aelliptical Arc(rx ry x-axis-rotation large-arc-flag sweep-flag x y)从当前点到 (x, y) 绘制一条椭圆弧。椭圆的大小和方向由两个半径 (rx, ry) 和x-axis-rotation定义,指示整个椭圆相对于当前坐标系怎样旋转(以度为单元)。 large-arc-flag 和 sweep-flag确定弧的绘制方式。Zclosepathnone通过将当前路径连接回当前子路径的初始点来关闭当前子路径。 比方: commands(‘M0 20 L50 50 L50 100 Z’)定义了一个三角形,起始于位置(0,20),接着绘制点(0,20)到点(50,50)的直线,再绘制点(50,50)到点(50,100)的直线,最后绘制点(50,100)到(0,20)的直线关闭路径,形成封闭三角形。
@Entry
@Component
struct PathExample {
build() {
    Column({space:20}){
      Image($r("app.media.Snip")) //默认加载图片
      .width(160)
      .height(90)

      Image($r("app.media.Snip")) //裁剪出一个矩形
      .width(160)
      .height(90)
          //commands路径绘制的命令字符串,单位为px, fill设置填充区域颜色。
      .mask(new Path({commands:"M0 0 L200 0 L200 300 L0 300 Z"}).fill(Color.Pink))

      Image($r("app.media.Snip"))
      .width(160)
      .height(90)
      //不使用commands不起作用,
      .mask(new Path({width:160, height:90}).fill(Color.Pink))

      Image($r("app.media.Snip")) //裁剪出一个三角形
      .width(160)
      .height(90)
          //commands路径绘制的命令字符串,单位为px, fill设置填充区域颜色。
      .mask(new Path({commands:"M0 0 L200 300 L0 300 Z"}).fill(Color.Pink))
    }
    .width("100%").height("100%").padding({top:20, bottom:20})
}
}
预览结果如下:
https://i-blog.csdnimg.cn/img_convert/96da0a5dc1c84d46a5274382a117943e.png
Rect:添加矩形遮罩,样比方下:
@Entry
@Component
struct RectExample {
build() {
    Column({space:20}){
      Image($r("app.media.Snip")) //默认加载图片
      .width(160)
      .height(90)

      Image($r("app.media.Snip")) //全部遮罩
      .width(160)
      .height(90)
      //Rect绘制矩形, fill设置填充区域颜色。
      .mask(new Rect({width:160,height:90}).fill(Color.Pink))

      Image($r("app.media.Snip"))
      .width(160)
      .height(90)
      //部分遮罩
      .mask(new Rect({width:90, height:90}).fill(Color.Pink))

    }
    .width("100%").height("100%").padding({top:20, bottom:20})
}
}
预览结果如下:
https://i-blog.csdnimg.cn/img_convert/f0f45da60629fce3e4b1760307c33697.png
3.2.剪切设置

clip是按照指定形状对当前组件举行剪切,剪切的参考系为当前组件的左上角坐标,参数如下:


[*]boolean:表示是否按照边缘表面举行裁剪,案比方下:
@Entry
@Component
struct ClipExample01 {
build() {
    Column({space:20}){
      Image($r("app.media.Snip"))
      .width(160)
      .height(90)
      .borderRadius(10) //设置圆角

      Column(){
      Image($r("app.media.Snip"))
          .width(160)
          .height(90)
      }.borderRadius(10) //设置圆角。对子组件无效

      Column(){
      }
      .width(160)
      .height(90)
      .backgroundColor("#3CB371")
      .borderRadius(10) //设置圆角。对子组件无效

      Column(){
      Image($r("app.media.Snip"))
          .width(160)
          .height(90)
      }
      .clip(true) //设置允许剪切,对所有子组件起作用
      .backgroundColor("#3CB371")
      .borderRadius(10) //设置圆角。对子组件无效
      
    }
    .width("100%")
    .height("100%")
    .padding(20)
}
}
预览结果如下:
https://i-blog.csdnimg.cn/img_convert/c912d10be2c2170dadbbd88c99f98327.png
ArkUI允许子组件超出父组件的绘制范围,假如不盼望超出可以使用该属性做下限制,样比方下所示:
@Entry
@Component
struct ClipExample02 {
build() {
    Row({space:10}){
      //没有设置clip属性,默认允许子组件超出父组件的绘制范围
      Column(){
      Text().size({width:20, height:80}).backgroundColor("#FFA07A")
      }.height("100%").layoutWeight(1).backgroundColor("#3CB371")


      Column(){
      Text().size({width:20, height:80}).backgroundColor("#FFA07A")
      }
      .height("100%")
      .layoutWeight(1)
      .backgroundColor("#3CB371")
      .clip(true)//添加clip属性为 true,表示子组件的绘制范围不能超出父组件
      
    }.width("100%").height(60)
}
}
第 1 个 Column 没有添加 clip 属性,则子组件的绘制区域可以超出父组件,第 2 个 Column 添加了 clip 而且属性值设置为true,则子组件超出父组件区域时被剪切到了。预览结果如下:
https://i-blog.csdnimg.cn/img_convert/1a3a464d21f2a2f3836328900dad0147.png


[*]Circle:把组件剪切成圆形,如下所示:
@Entry
@Component
struct ClipExample03 {
build() {
    Column({space:20}){
      Image($r("app.media.Snip"))// 默认图片
      .width(160)
      .height(90)

      Image($r("app.media.Snip"))// 居左裁剪出一个圆
      .width(160)
      .height(90)
      //宽高一致,则按照90为直径
      .clip(new Circle({width:90, height:90}).fill("#66CDAA"))

      Image($r("app.media.Snip"))// 居中裁剪出一个圆
      .width(160)
      .height(90)
      //宽高不一致,则按照小的值为直径
      .clip(new Circle({width:160, height:90}).fill("#66CDAA"))

      Image($r("app.media.Snip"))// 居右裁剪出一个圆
      .width(160)
      .height(90)
      .clip(new Circle({width:230, height:90}).fill("#66CDAA"))

    }.width("100%").height("100%").padding({top:20, bottom:20})
}
}
预览结果如下:
https://i-blog.csdnimg.cn/img_convert/4774505e8a1496d8ae394d475532b946.png


[*]Ellipse:把组件剪切成椭圆形,如下:
@Entry
@Component
struct ClipExample04 {
build() {
    Column({space:20}){
      Image($r("app.media.Snip"))// 默认图片
      .width(160)
      .height(90)

      Image($r("app.media.Snip"))// 裁剪出一个椭圆
      .width(160)
      .height(90)
      .clip(new Ellipse({width:160, height:90}).fill("#66CDAA"))

      Image($r("app.media.Snip"))// 裁剪出一个椭圆
      .width(160)
      .height(90)
      //Ellipse裁剪出椭圆
      .clip(new Ellipse({width:130, height:90}).fill("#66CDAA"))

    }.width("100%").height("100%").padding({top:20, bottom:20})
}
}
预览结果如下:
https://i-blog.csdnimg.cn/img_convert/c3b92f35041844692d057354a014d0fe.png


[*]Path:把组件按照Path剪切出对应形状,Path使用commands才生结果,如下:
@Entry
@Component
struct ClipExample05 {
build() {
    Column({space:20}){
      Image($r("app.media.Snip"))// 默认图片
      .width(160)
      .height(90)

      Image($r("app.media.Snip"))// 使用commands参数起作用,绘制出图形
      .width(160)
      .height(90)
      .clip(new Path({commands:"M0 0 L150 0 L300 150 L0 300 Z"}).fill("#66CDAA"))

      Image($r("app.media.Snip"))//直接设置宽和高不起作用
      .width(160)
      .height(90)
      .clip(new Path({width:130, height:90}).fill("#66CDAA"))

      Image($r("app.media.Snip"))//使用commands参数起作用,绘制出图形
      .width(160)
      .height(90)
      //vp2px(80)将vp(屏幕密度)单位的数值转换为以px(屏幕物理像素单位。)为单位的数值。
      .clip(new Path({width:130, height:90, commands:"M0 0 L" + vp2px(80) + " 0 L" + vp2px(80) + " " + vp2px(45) + " L0 " + vp2px(45) + " Z"}).fill("#66CDAA"))

    }.width("100%").height("100%").padding({top:20, bottom:20})
}
}
预览结果如下:
https://i-blog.csdnimg.cn/img_convert/d69e71f397ac37225320dab355a0bf02.png


[*]Rect:把组件按照指定区域剪切出对应形状,如下:
@Entry
@Component
struct ClipExample06 {
build() {
    Column({space:20}){
      Image($r("app.media.Snip"))// 默认图片
      .width(160)
      .height(90)

      Image($r("app.media.Snip"))
      .width(160)
      .height(90)
      .clip(new Rect({width:100, height:100}).fill("#66CDAA"))

      Image($r("app.media.Snip"))
      .width(160)
      .height(90)
      .clip(new Rect({width:90, height:45}).fill("#66CDAA"))

    }.width("100%").height("100%").padding({top:20, bottom:20})
}
}
预览结果如下:
https://i-blog.csdnimg.cn/img_convert/30c0a018691f958ce114fac06c919237.png
四、公共提示类属性

为组件绑定弹出式菜单,弹出式菜单以垂直列表形式显示菜单项,可通过长按、点击或鼠标右键触发。
阐明


[*]CustomBuilder里不支持再使用bindMenu、bindContextMenu弹出菜单。多级菜单可使用Menu组件。
[*]弹出菜单的文本内容不支持长按选中。
属性
名称参数类型描述bindMenuArray | CustomBuilder给组件绑定菜单,点击后弹出菜单。弹出菜单项支持文本和自定义两种功能。bindContextMenu8+content: CustomBuilder,responseType: ResponseType
给组件绑定菜单,触发方式为长按或者右键点击,弹出菜单项必要自定义。 MenuItem
名称类型描述valuestring菜单项文本。action() => void点击菜单项的事件回调。 4.1:bindMenu

bindMenu 表示给当前组件绑定一个菜单项,用户点击组件后弹出菜单, bindMenu 如下:


[*]单项文本实现:当 content 类型为 { value: string; action: () => void } 时, value 表示要显示的菜单文本, action 表示点击该文本的事件回调,如下所示:
import prompt from '@system.prompt';

@Entry
@Component
struct BindMenuExample01 {
build() {
    Column({space:20}){
      Button("bindMenu")
      .width(120)
      .height(50)
      .onClick(()=>{
          prompt.showToast({message:"bindMenu"})
      })
      .bindMenu([
          {value:"菜单1",action:()=>{
            //显示文本提示框
            prompt.showToast({message:"菜单1"})
          }},
          {value:"菜单2",action:()=>{
            //显示文本提示框
            prompt.showToast({message:"菜单2"})
          }},
          {value:"菜单3",action:()=>{
            //显示文本提示框
            prompt.showToast({message:"菜单3"})
          }}
      ])
    }.width("100%").height("100%").padding(20)
}
}
预览结果如下:
https://i-blog.csdnimg.cn/img_convert/b2594b59733f2e9c9266b818538852e4.gif
上面使用单项文本实现一个菜单,文字太小而且样式和结构均无法修改,这种方式UI范围性太大,为了满意多样式场景需求,ArkUI框架提供了 CustomBuilder 方式允许开发者自定义 UI 描述。


[*]CustomBuilder方式实现:CustomBuilder 在 common.d.ts 文件中定义,源码定义如下:
CustomBuilder 可代表一个空类型也可以表示一个返回恣意类型的函数,自定义 UI 描述使用 @Builder 装饰器装饰一个方法,该方法功能和语法规范和 build 函数相同,返回一个 UI 结构,语法格式如下:
@Builder function_name() { // @Builder修饰一个方法
// UI布局
Column() {
}
}
用户自定义 UI 实现,就是使用 @Builder 修饰一个方法,该方法返回一个 UI 结构即可,案比方下:
import prompt from '@system.prompt'
@Entry
@Component
struct CustomBuilderExample {
//自定义菜单组件
@Builder ButtonMenuBuilder(){
    Column(){
      Text("菜单1")
      .width("100%")
      .height(50)
      .fontSize(20)
      .fontColor(Color.White)
      .textAlign(TextAlign.Center)
      .onClick(()=>{
          prompt.showToast({message:"菜单1"})
      })

      //提供分隔器组件,分隔不同内容块/内容元素。
      Divider()
      .width("100%").height(1).backgroundColor(Color.White)

      Text("菜单2")
      .width("100%")
      .height(50)
      .fontSize(20)
      .fontColor(Color.White)
      .textAlign(TextAlign.Center)
      .onClick(()=>{
          prompt.showToast({message:"菜单2"})
      })

      //提供分隔器组件,分隔不同内容块/内容元素。
      Divider()
      .width("100%").height(1).backgroundColor(Color.White)

      Text("菜单3")
      .width("100%")
      .height(50)
      .fontSize(20)
      .fontColor(Color.White)
      .textAlign(TextAlign.Center)
      .onClick(()=>{
          prompt.showToast({message:"菜单3"})
      })
    }
    .width(200)
    .backgroundColor("#2E8B57")
}

build() {
    Column({space:10}){
      Button("bindMenu")
      .width(120)
      .height(50)
      .onClick(() => {//同时设置onClick
          prompt.showToast({message:"hi Augus"})
      })
      //调用自定义的菜单组件
      .bindMenu(this.ButtonMenuBuilder)//绑定自定义菜单
    }
    .width("100%")
    .height("100%")
    .padding(20)
}
}
预览结果如下:
https://i-blog.csdnimg.cn/img_convert/bbd367eacbee91629611bf73e4a2c25d.gif
4.2.bindContextMenu

bindContextMenu 在长按或者右键点击组件是才会触发显示菜单项,bindContextMenu 定义如下:
declare class CommonMethod<T> {
bindContextMenu(content: CustomBuilder, responseType: ResponseType
): T;
}
参数阐明:


[*] content:参数只支持使用 CustomBuilder 自定义 UI 一种方式,
[*] responseType:触发弹窗的相应类型,
ResponseType
定义了一下两种类型:

[*]LongPress:通过长按触发菜单弹出。
[*]RightClick:通过鼠标右键触发菜单弹出。(为了PC端 准备)

代码如下:
import prompt from '@system.prompt'@Entry@Componentstruct CustomBuilderExample {//自定义菜单组件@Builder ButtonMenuBuilder(){    Column(){      Text("菜单1")      .width("100%")      .height(50)      .fontSize(20)      .fontColor(Color.White)      .textAlign(TextAlign.Center)      .onClick(()=>{          prompt.showToast({message:"菜单1"})      })      //提供分隔器组件,分隔不同内容块/内容元素。      Divider()      .width("100%").height(1).backgroundColor(Color.White)      Text("菜单2")      .width("100%")      .height(50)      .fontSize(20)      .fontColor(Color.White)      .textAlign(TextAlign.Center)      .onClick(()=>{          prompt.showToast({message:"菜单2"})      })      //提供分隔器组件,分隔不同内容块/内容元素。      Divider()      .width("100%").height(1).backgroundColor(Color.White)      Text("菜单3")      .width("100%")      .height(50)      .fontSize(20)      .fontColor(Color.White)      .textAlign(TextAlign.Center)      .onClick(()=>{          prompt.showToast({message:"菜单3"})      })    }    .width(200)    .backgroundColor("#2E8B57")}build() {    Column({space:10}){      Button("bindMenu")      .width(120)      .height(50)      .onClick(() => {//同时设置onClick和bindMenu,onClick不生效          prompt.showToast({message:"hi Augus"})      })      //调用自定义的菜单组件      .bindContextMenu(this.ButtonMenuBuilder, ResponseType
.LongPress)//长按绑定菜单    }    .width("100%")    .height("100%")    .padding(20)}} 预览结果如下:
https://i-blog.csdnimg.cn/img_convert/8adae803b26f3d13500a6d91852908ab.gif
4.3.bindPopup

bindPopup 和 bindMenu 类似,都是弹出一个可选项提示框, bindPopup 接口如下:
名称参数类型描述bindPopupshow: boolean,popup: PopupOptions | CustomPopupOptions8+给组件绑定Popup,点击弹出弹窗。show: 创建页面弹窗提示是否默认显示,默认值为false。popup: 配置当前弹窗提示的参数。 参数阐明如下:


[*]show:创建 Popup 弹窗时是否默认显示,默认值为 false 。
[*]popup:Popup 的显示配置,参数支持 PopupOptions 和 CustomPopupOptions 两种类型,他们分别如下所示:
1)PopupOptions配置如下:
declare interface PopupOptions {
message: string;                                       // 显示的信息提示
placementOnTop?: boolean;                              // 是否显示在组件上方,默认值为 false
primaryButton?: {                                        // 第一个按钮的配置
    value: string;                                       // 按钮的文字
    action: () => void;                                    // 按钮的点击回调
};
secondaryButton?: {                                    // 第二个按钮的配置
    value: string;                                       // 按钮的文字
    action: () => void;                                    // 按钮的事件回调
};
onStateChange?: (event: { isVisible: boolean }) => void; // Popup可见性变化的回调
}
阐明:


[*]message: Popup 显示的提示文字。
[*]placementOnTop: Popup 是否显示在组件上方。
[*]primaryButton: Popup 显示按钮配置。
[*]secondaryButton: Popup 显示按钮配置。
[*]onStateChange: Popup 弹窗状态(是否可见性)变化事件回调
案例代码如下:
import prompt from '@system.prompt'
@Entry
@Component
struct BindPopupExample {
//默认状态值
@State isPopup:boolean = false

build() {
    Column({space:20}){
      Button("bindPopup")
      .width(120)
      .height(50)
      //this.isPopup为true的时候,才会显示
      .bindPopup(this.isPopup, {
          message: "获取摄像头权限",//显示的内容
          placementOnTop: true,//显示在组件上方
          onStateChange: ((state)=>{ // Popup可以见到菜单变化的回调
            prompt.showToast({message: `弹出是否可见:${state.isVisible}`})
          }),
          primaryButton:{
            value:"同意",
            action:()=>{
            prompt.showToast({message: "允许获取权限"})
            //修改状态
            this.isPopup = !this.isPopup
            }
          },
          secondaryButton:{
            value:"不同意",
            action:()=>{
            prompt.showToast({message: "不允许获取权限"})
            //修改状态
            this.isPopup = !this.isPopup
            }
          }
      })
      .onClick(()=>{
          prompt.showToast({message:"bindPopup按钮测试"})
          //修改状态
          this.isPopup = !this.isPopup
      })
    }
    .width("100%")
    .height("100%")
    .padding(20)
}
}
预览结果如下:
https://i-blog.csdnimg.cn/img_convert/b55734b83f672a2a7406f32838500094.gif
2)CustomPopupOptions配置如下:
declare interface CustomPopupOptions {
builder: CustomBuilder;
placement?: Placement;
maskColor?: Color | string | Resource | number;
popupColor?: Color | string | Resource | number;
enableArrow?: boolean;
autoCancel?: boolean;
onStateChange?: (event: { isVisible: boolean }) => void;
}
参数如下:


[*]builder:自定义 Popup 。
[*]placement: Popup 的相对位置。
[*]maskColor: Popup 蒙层颜色。
[*]popupColor: Popup 配景颜色。
[*]enableArrow: Popup 是否显示箭头。
[*]autoCancel: Popup 是否自动隐藏。
[*]onStateChange: Popup 弹出状态(窗口可见性)变化的回调。
案例代码如下:
import prompt from '@system.prompt'
@Entry
@Component
struct BindPopupExample02 {
//默认状态值
@State isPopup:boolean = false

//自定义UI组件
@Builder PopupButton(){
    Row(){
      Text("分享").width(80).height("100%").fontSize(20).fontColor(Color.White).textAlign(TextAlign.Center).backgroundColor("#3CB371").onClick(()=>{
      prompt.showToast({message:"分享"})
      })
      Divider().width(3).height("100%").backgroundColor(Color.White)

      Text("转发").width(80).height("100%").fontSize(20).fontColor(Color.White).textAlign(TextAlign.Center).backgroundColor("#3CB371").onClick(()=>{
      prompt.showToast({message:"转发"})
      })

      Divider().width(3).height("100%").backgroundColor(Color.White)

      Text("点赞").width(80).height("100%").fontSize(20).fontColor(Color.White).textAlign(TextAlign.Center).backgroundColor("#3CB371").onClick(()=>{
      prompt.showToast({message:"点赞"})
      })

    }.height(50)
}

build() {
    Column({space:20}){
      Button("bindPopup")
      .width(120)
      .height(50)
      //this.isPopup为true的时候,才会显示
      .bindPopup(this.isPopup, {
          builder: this.PopupButton, //使用自定义UI
          placement:Placement.Bottom, //显示到下方按钮
          maskColor: Color.Pink,      //蒙层颜色
          popupColor: Color.Orange,    //背景颜色
          enableArrow: true,         //显示箭头
          autoCancel:true,         //设置自动隐藏
          onStateChange:((state)=>{
            prompt.showToast({message:`弹窗是否可见:${state.isVisible}`})
          })
      })
      .onClick(()=>{
          prompt.showToast({message:"bindPopup按钮测试"})
          //修改状态
          this.isPopup = !this.isPopup
      })
    }
    .width("100%")
    .height("100%")
    .padding(20)
}
}
预览结果如下:
https://i-blog.csdnimg.cn/img_convert/973a4cb0b4c5454c7cb1f624bd04f769.gif

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 【HarmonyOS 5.0】第十三篇-ArkUI公共属性(二)