1、HarmonyOS 子组件如何拦截触摸事件?

嵌套在页面中的 Scroll 组件内部,尝试在 onTouch 中通过 event.stopPropagation() 拦截触摸事件,以便在子组件中滑动时,不会触发 Scroll 的整体上下滑动。但发现这样没有达到效果,请问该如何处理?

Stack() {
  Canvas(this.pickCanvas)
}.width('100%').height(200).onTouch((event: TouchEvent) => {
  event.stopPropagation()
}

可以尝试下给Canvas组件加上.hitTestBehavior(HitTestMode.Block),参考文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-universal-attributes-hit-test-behavior-V5

设置组件的触摸测试类型。ArkUI开发框架在处理触屏事件时,会在触屏事件触发前,进行按压点和组件区域的触摸测试来收集需要响应触屏事件的组件,然后基于触摸测试结果分发相应的触屏事件。hitTestBehavior属性可以设置不同的触摸测试响应模式,影响组件的触摸测试收集结果,最终影响后续的触屏事件分发,具体影响参考HitTestMode枚举说明。

长按Canvas区域,进入Canvas组件,单击Canvas以外区域,退出Canvas组件,可进行整体scroll组件滑动手势监听

参考链接:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-basic-gestures-tapgesture-V5

@Entry
@Component
export struct PageE {

  @State isCheck:boolean = false;

  private scrollerView: Scroller = new Scroller()
  private settings: RenderingContextSettings = new RenderingContextSettings(true)
  private chartCanvas: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)

  build() {
    Flex() {
      Scroll(this.scrollerView) {
        Column() {
          Text("Scroll Area").width("100%").height("40%").backgroundColor(0X330000FF)

          Stack() {
            Canvas(this.chartCanvas)// .width(display.getDefaultDisplaySync().width / display.getDefaultDisplaySync().scaledDensity)
              .width('100%')
              .height('100%')
              .onReady(() => {
                let c = this.chartCanvas
                c.fillStyle = "#f00"
                c.fillRect(20, 20, c.width - 40, c.height - 40)
              }).onTouch((event: TouchEvent) => {
              console.log("111")
              // event.stopPropagation()
              // 此处获取 touch 事件用于指导 canvas 的绘制,比如图表的拖动这样的效果
              // 期望当在图表中拖动时,不会导致外层的 Scroll 的滑动
            })
              .hitTestBehavior(this.isCheck ? HitTestMode.Block : HitTestMode.Default)
              .gesture(
                LongPressGesture()
                  .onAction((event: GestureEvent) => {
                    console.log("111222")
                    if(!this.isCheck){
                      this.isCheck = !this.isCheck
                    }
                  }),GestureMask.IgnoreInternal)
          }

          .backgroundColor("#ffff00").width('100%').height(200)

          Text("Scroll Area")
            .width("100%").height("40%").backgroundColor(0X330000FF)
        }
      }
      .priorityGesture(
        TapGesture()
          .onAction((event: GestureEvent) => {
            console.log("333333")
            if(this.isCheck){
              this.isCheck = !this.isCheck
            }
          }),GestureMask.Normal
      )
      .width("100%").height("100%")
    }.width('100%').height('100%').backgroundColor(0xDCDCDC).padding(20)
  }
}
2、HarmonyOS 页面上的弹窗如何禁用侧滑返回?

页面上的弹窗如何禁用侧滑返回,目前页面上设置禁用侧滑, .onBackPressed(() => true),但是该页面上的弹窗仍然会响应侧滑

使用onwilldismiss参考链接:https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkui/arkui-ts/ts-methods-custom-dialog-box.md#customdialogcontrolleroptions%E5%AF%B9%E8%B1%A1%E8%AF%B4%E6%98%8E

3、HarmonyOS 在ViewModel产生的数据如何驱动UI更新?

如何在ViewModel产生的数据如何驱动UI更新? 组件是可以使用@State等相关的去驱动UI更新。

在对应加上@ObjectLink和@Observed类装饰器试下。参考文档 :https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/arkts-observed-and-objectlink-V5#%E5%9C%A8%E5%AD%90%E7%BB%84%E4%BB%B6%E4%B8%AD%E7%BB%99objectlink%E8%A3%85%E9%A5%B0%E7%9A%84%E5%8F%98%E9%87%8F%E8%B5%8B%E5%80%BC

4、HarmonyOS Text如何知道触发了TextOverflow.Ellipsis?

可参考以下demo:

import measure from '@ohos.measure'
@Entry
@Component
struct MeasurePage {
  @State rawTitle: string = "1月16日,国务院新闻办公室举行新闻发布会,介绍2024年春运形势及工作安排。从2月9日(除夕)00:00到2月17日(正月初八)24:00,免费9天。1月16日,国务院新闻办公室举行新闻发布会,介绍2024年春运形势及工作安排"
  // @State rawTitle: string = "1月16日,国务院新闻办公室举行新闻发布会"
  @State title: string = this.rawTitle //
  @State suffixStr: string = ""
  expanded: Boolean = true
  titleWidth: number = 350
  needProcess: boolean = true
  ellipsis: string = "..."
  EXPAND_STR: string = "展开"
  COLLAPSE_STR: string = "收起"
  MAX_LINES: number =2;
  fontSize:number = 16

  aboutToAppear(): void {
    this.process();
  }
  process(): void {
    if (this.expanded) {
      this.collapseText();
    } else {
      this.expandText();
    }
  }
  expandText(): void {
    console.log('testTag: ' + this.needProcess);
    if (this.needProcess) {
      this.suffixStr = this.COLLAPSE_STR; //收起
      this.expanded = true;
      this.title = this.rawTitle;
    }
  }
  collapseText(): void {
    if (!this.needProcess) {
      return;
    }
    let titleSize : SizeOptions = measure.measureTextSize({
      textContent: this.rawTitle,
      constraintWidth: this.titleWidth,
      fontSize: this.fontSize
    })
    let twoLineSize : SizeOptions = measure.measureTextSize({
      textContent: this.rawTitle,
      constraintWidth: this.titleWidth,
      fontSize: this.fontSize,
      maxLines: this.MAX_LINES
    })
    //文本未超过限制行数,不进行展开、收起处理
    if ((titleSize.height as number) == (twoLineSize.height as number)) {
      this.needProcess = false;
      return;
    }
    console.log('test row height:' + titleSize.height)
    console.log('test twoLineSize height:' + twoLineSize.height)
    let clipTitle: string = this.rawTitle
    this.suffixStr = this.EXPAND_STR;
    while ((titleSize.height as number) > (twoLineSize.height as number)) {
      this.expanded = true;
      // 可以修改其他计算算法提高性能
      clipTitle = clipTitle.substring(0, clipTitle.length - 1);
      titleSize = measure.measureTextSize({
        // textContent: clipTitle + this.ellipsis + this.suffixStr,
        textContent: clipTitle + this.ellipsis ,
        constraintWidth: this.titleWidth,
        fontSize: this.fontSize
      })
      console.log("test while clipTitle:" + clipTitle)
      console.log("test while clipTitle height:" + titleSize.height)
    }
    console.log("test clipTitle:" + clipTitle)
    this.title = clipTitle + this.ellipsis
    this.expanded = false;
  }
  build() {
    Row() {
      Column() {
        Text(){
          Span(this.title)
        }
        .fontSize(this.fontSize)
        .id("title")
        .width(this.titleWidth)
        if (this.needProcess) {
          Text(this.suffixStr)
            .fontColor(Color.Orange)
            .onClick((event) => {
            this.process();
          })
        }
      }
      .width('100%')
      .alignItems(HorizontalAlign.Start)
    }
    .height('100%')

  }
}
5、HarmonyOS 获取view在屏幕的坐标?

详细请参考:https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-universal-attributes-component-id-V5

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐