HarmonyOS 鸿蒙Next中RichEditor中this.controller.getLayoutManager().getGlyphPositionAtCoordinate(x, y)拿到的位置不准确,有没有更好的办法拿到点击imageSpan的offset

HarmonyOS 鸿蒙Next中RichEditor中this.controller.getLayoutManager().getGlyphPositionAtCoordinate(x, y)拿到的位置不准确,有没有更好的办法拿到点击imageSpan的offset

我想实现在输入框中插入待办清单功能,就是插入待办和已办图标,点击之后替换imageSpan,需要做到点击imageSpan之后能拿到该ImageSpan的offset,插入的时候确实是知道位置,但是后续如果imageSpan之前插入内容后,这个imageSpan的offset就变化了,所以点击后得重新获取位置。

RichEditor 中 this.controller.getLayoutManager().getGlyphPositionAtCoordinate(x, y) 拿到的位置不准确,有没有更好的办法拿到点击imageSpan的offset?

this.controller.addImageSpan($r('app.media.cb_normal'), {
      offset: position,
      imageStyle: {
        size: [iconSize, iconSize],
        verticalAlign: ImageSpanAlignment.CENTER,
        layoutStyle: {
          margin: {
            right: 2
          }
        }
      },
      gesture: {
        onClick: (event) => {
          event.preventDefault()

          let x = event.windowX
          let y = event.windowY

          let position = this.controller.getLayoutManager().getGlyphPositionAtCoordinate(x, y).position
          this.replaceTodoDone(position)
        }
      }
    })

更多关于HarmonyOS 鸿蒙Next中RichEditor中this.controller.getLayoutManager().getGlyphPositionAtCoordinate(x, y)拿到的位置不准确,有没有更好的办法拿到点击imageSpan的offset的实战教程也可以访问 https://www.itying.com/category-93-b0.html

6 回复

绑定的点击事件里面,这样写就可以获取到offset了

let position = this.controller.getLayoutManager().getGlyphPositionAtCoordinate(vp2px(event.x), vp2px(event.y)).position
console.log("offset:" + JSON.stringify(position));

getGlyphPositionAtCoordinate需要的参数但是是px,你之前获取的是相对于窗口左上角的坐标,所以转换索引不对

更多关于HarmonyOS 鸿蒙Next中RichEditor中this.controller.getLayoutManager().getGlyphPositionAtCoordinate(x, y)拿到的位置不准确,有没有更好的办法拿到点击imageSpan的offset的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


牛逼!!!这个获取的是对的了,

可以考虑换个思路,使用RichEditorController的getSpans 方法获取到所有的spans。然后找到目标的imageSpan,计算出当前imageSpan的offset。最后做替换。

[
    {
        "offsetInSpan": [0, 1],
        "spanPosition": {
            "spanIndex": 0,
            "spanRange": [0, 1]
        },
        "value": "L",
        "previewText": "",
        "textStyle": {
            "fontColor": "#FF182431",
            "fontFeature": "\"pnum\" 1",
            "fontSize": 16,
            "fontStyle": 0,
            "lineHeight": 0,
            "letterSpacing": 0,
            "fontWeight": 10,
            "fontFamily": "HarmonyOS Sans",
            "decoration": {
                "type": 0,
                "color": "#FF182431",
                "style": 0
            },
            "textShadow": []
        },
        "paragraphStyle": {
            "textAlign": 0,
            "leadingMargin": ["0.00px", "0.00px"],
            "wordBreak": 2,
            "lineBreakStrategy": 0
        }
    },
    {
        "offsetInSpan": [0, 1],
        "spanPosition": {
            "spanIndex": 1,
            "spanRange": [1, 2]
        },
        "valueResourceStr": "file:///Applications/DevEco-Studio.app/Contents/sdk/default/hms/previewer/resources/resources/resources/base/media/wifi_router_fill.svg",
        "imageStyle": {
            "size": [0, 0],
            "verticalAlign": 2,
            "objectFit": 2,
            "layoutStyle": {
                "borderRadius": "0.00px",
                "margin": "[NA,2.00vp,NA,NA]"
            }
        }
    },
    {
        "offsetInSpan": [0, 83],
        "spanPosition": {
            "spanIndex": 2,
            "spanRange": [2, 85]
        },
        "value": "oaded and parsed script entry|entry|1.0.0|src/main/ets/entryability/EntryAbility.ts",
        "previewText": "",
        "textStyle": {
            "fontColor": "#FF182431",
            "fontFeature": "\"pnum\" 1",
            "fontSize": 16,
            "fontStyle": 0,
            "lineHeight": 0,
            "letterSpacing": 0,
            "fontWeight": 10,
            "fontFamily": "HarmonyOS Sans",
            "decoration": {
                "type": 0,
                "color": "#FF182431",
                "style": 0
            },
            "textShadow": []
        },
        "paragraphStyle": {
            "textAlign": 0,
            "leadingMargin": ["0.00px", "0.00px"],
            "wordBreak": 2,
            "lineBreakStrategy": 0
        }
    }
]

详情请参考RichEditor文档:RichEditor文档

感谢回复,不过这个方案我考虑了,主要问题在于,待办有很多个,而这个Span又不支持添加自定义数据,查询出来是不知道我点击的到底是哪一个。

在HarmonyOS的鸿蒙Next中,RichEditor组件用于处理富文本编辑。getGlyphPositionAtCoordinate(x, y)方法用于获取指定坐标处的字符位置,但在处理ImageSpan时,可能会出现位置不准确的情况。这是因为ImageSpan在文本布局中占据的空间与普通字符不同,getGlyphPositionAtCoordinate方法可能无法准确识别其边界。

为了更准确地获取点击ImageSpan的偏移量,可以使用RichEditorgetOffsetForPosition(x, y)方法。该方法返回指定坐标处最接近的字符偏移量,适用于处理包含ImageSpan的富文本。

示例代码如下:

let offset = this.controller.getOffsetForPosition(x, y);

getOffsetForPosition方法会根据传入的坐标(x, y),返回最接近的字符偏移量。对于ImageSpan,该方法会返回ImageSpan在文本中的起始位置或结束位置,具体取决于点击的位置。

此外,可以通过this.controller.getText()获取当前文本内容,再结合offset来判断点击的是否为ImageSpan。例如:

let text = this.controller.getText();
let span = text.getSpans(offset, offset, ImageSpan)[0];
if (span != null) {
    // 点击的是ImageSpan
}

这种方法可以更准确地处理ImageSpan的点击事件,避免因getGlyphPositionAtCoordinate方法的不准确而导致的错误。

在HarmonyOS鸿蒙Next中,RichEditorthis.controller.getLayoutManager().getGlyphPositionAtCoordinate(x, y)方法可能因坐标系转换或布局计算问题导致位置不准确。建议使用TextSpanrecognizer属性,通过TapGestureRecognizer监听点击事件,再结合TextPositionTextSelection来精确定位点击的ImageSpan的偏移量(offset)。这样可以更准确地获取点击位置。

回到顶部