HarmonyOS componentSnapshot.createFromBuilder长列表截图不全

需要将一个列表的视图内容保存到本地一张图片,使用组件componentSnapshot.get以及componentSnapshot.createFromBuilder都无法获取视图完整内容,是否有解决方案?

HarmonyOS
2024-12-25 12:36:25
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
FengTianYa

请参考示例如下:

import componentSnapshot from '@ohos.arkui.componentSnapshot'
import image from '@ohos.multimedia.image'
import { common } from '@kit.AbilityKit';
import window from '@ohos.window';

@Entry
@Component
struct Index {
  private context = getContext(this) as common.UIAbilityContext;
  private settings: RenderingContextSettings = new RenderingContextSettings(true);
  private canvasContext: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
  private offCanvas: OffscreenCanvas = new OffscreenCanvas(600, 2100)
  private offContext = this.offCanvas.getContext("2d", this.settings)
  @State pixmap: image.PixelMap | undefined = undefined
  @State scrollWidth: number = 0
  @State ScrollHeight: number = 0
  @State screenWidth: number = 0
  @State screenHeight: number = 0
  @State shareStas: boolean = false
  scroller: Scroller = new Scroller()
  private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

  aboutToAppear(): void {

    window.getLastWindow(this.context, (err, data) => {
      if (err.code) {
        console.error('Failed to obtain the top window. Cause: ' + JSON.stringify(err));
        return;
      }

      let properties = data.getWindowProperties();
      // 单位px 转成 vp
      this.screenWidth = px2vp(properties.windowRect.width)
      this.screenHeight = px2vp(properties.windowRect.height)

      console.info('window. Data: ' + this.screenWidth + '-------' + this.screenHeight);
    });
  }

  // 长屏拼接截图
  createSnap = async () => {
    let i = 0

    // 这个判断条件可以优化,根据scroll的实际长度和一屏长度,计算次数
    while (!this.scroller.isAtEnd()) {
      // 一定要放在最上面
      this.scroller.scrollPage({ next: true })
      // 默认单位都是vp
      // 图片资源,绘制区域左上角在x轴的位置,绘制区域左上角在y 轴的位置,绘制区域的宽度,绘制区域的高度
      let curSnip: image.PixelMap = await componentSnapshot.get("builder")
      this.offContext.drawImage(curSnip, 0, this.ScrollHeight * i, this.scrollWidth, this.ScrollHeight);

      i++
    }

    this.pixmap = this.offContext.getPixelMap(0, 0, this.screenWidth, 2100); // 2100也可以优化,我这里随便写的数字
  }

  build() {
    Stack() {
      Scroll(this.scroller) {
        Column() {
          ForEach(this.arr, (item: number) => {
            Text(item.toString())
              .width('90%')
              .height(150)
              .backgroundColor(Color.Orange)
              .borderRadius(15)
              .fontSize(16)
              .textAlign(TextAlign.Center)
              .margin({ top: 10 })
          }, (item: string) => item)
        }.width('100%')
      }
      .scrollable(ScrollDirection.Vertical) // 滚动方向纵向
      .scrollBar(BarState.On) // 滚动条常驻显示
      .scrollBarColor(Color.Gray) // 滚动条颜色
      .scrollBarWidth(10) // 滚动条宽度
      .friction(0.6)
      .edgeEffect(EdgeEffect.None)
      .onScrollEdge((side: Edge) => {
        console.info('To the edge')
      })
      .onReachStart(() => {
        // init会默认触发一次,shareStas 标记
        if (this.shareStas) {
          this.createSnap()
        }

        console.log('onReachStart----------')
      })
      .onScrollStop(() => {
        console.info('Scroll Stop')
      })
      .onAreaChange((oldValue: Area, newValue: Area) => {
        // 单位是vp
        this.scrollWidth = newValue.width as number;
        this.ScrollHeight = newValue.height as number
        console.log(`Scroll component width: ${this.scrollWidth}, height: ${this.ScrollHeight}`);
      })
      .id("builder")

      Scroll() {
        Column() {
          Button('生成截图')
            .onClick(() => {
              const yOffset: number = this.scroller.currentOffset().yOffset;
              console.log('yOffset----', yOffset)
              if (yOffset !== 0) {
                // scroll 没有置顶
                this.shareStas = true;
                this.scroller.scrollEdge(Edge.Top)

              } else {
                this.createSnap()
              }
            })
          Image(this.pixmap)
            .border({ color: Color.Black, width: 2 })
        }
      }.backgroundColor(Color.Red)
    }
  }
}
分享
微博
QQ
微信
回复
2024-12-25 15:16:30
相关问题
HarmonyOS 读取内容不全
38浏览 • 1回复 待解决
HarmonyOS web显示不全
683浏览 • 1回复 待解决