【每日学点鸿蒙知识】查看触摸热区范围、直接赋值到剪贴板、组件截图、横竖屏切换、防截图等

1、如何查看触摸热区范围?

前只能通过自定义的方式获取responseRegion。参考文档:触摸热区设置

@Entry
@Component
struct TouchTargetExample {
  @State text: string = ''
  @State x:number = 0
  @State y:number = 0
  @State reg_width:string = '50%'
  @State reg_height:string = '100%'

  build() {
    Column({ space: 20 }) {
      Text("{x:0,y:0,width:'50%',height:'100%'}")

      // 热区宽度为按钮的一半,点击右侧无响应
      Button('button')
        .responseRegion({ x: this.x, y: this.y, width: this.reg_width, height: this.reg_height })
        .onClick(() => {
          this.text = 'button clicked'
          console.log('button clicked: '+this.x+' '+this.y+' '+this.reg_width+' '+this.reg_height)
        })

      Text(this.text).margin({ top: 10 })
    }.width('100%').margin({ top: 100 })
  }
}

2、如何将内容直接复制到剪贴板?

直接把文本上的内容添加进剪切板,不需要跳出选择文本的弹窗,直接复制成功。参考代码如下:

import { pasteboard  } from '@kit.BasicServicesKit';
import { promptAction } from '@kit.ArkUI';

@Entry
@Component
export struct CopyText {
  private textContent: string = '复制我'

  build() {
    Column() {
      Text(this.textContent)
        .fontSize($r('sys.float.ohos_id_text_size_body3'))
        .borderRadius(9)
        .borderWidth(1)
        .padding({ left: 8, right:8})
        .fontColor($r('sys.color.ohos_id_color_text_primary'))
        .fontWeight(FontWeight.Medium)
        .opacity($r('sys.float.ohos_id_alpha_content_secondary'))
        .onClick(() => copyText(this.textContent))
    }
  }
}

function copyText(text: string) {
  const pasteboardData = pasteboard.createData(pasteboard.MIMETYPE_TEXT_PLAIN, text)
  const systemPasteboard = pasteboard.getSystemPasteboard()
  systemPasteboard.setData(pasteboardData) // 将数据放入剪切板
  systemPasteboard.getData().then((data) => {
    if (data) {
      promptAction.showToast({ message: '复制成功' })
    } else {
      promptAction.showToast({ message: '复制失败' })
    }
  })
}

3、组件截图怎么保存将pixelMap存储到系统相册或应用沙箱?

步骤一:确认功能需要使用的能力为组件截图能力:componentSnapshot

截图能力有窗口截图能力 window.snapshot()和 组件截图能力 @ohos.arkui.componentSnapshot。不同的能力范围根据业务选择合适的PAI 解决问题。

步骤二:应用授权以及配置

保存到系统相册需要 申请相册管理模块权限'ohos.permission.WRITE_IMAGEVIDEO'module.json5 配置权限

"requestPermissions": [
  {
    "name": "ohos.permission.WRITE_IMAGEVIDEO",
    "reason": "$string:reason",
    "usedScene": {
      "abilities": [
        "EntryFormAbility"
      ],
      "when": "inuse"
    }
  },
]

页面入口获取权限

import { abilityAccessCtrl, common, Permissions } from '@kit.AbilityKit';
const permissions: Array<Permissions> = ['ohos.permission.WRITE_IMAGEVIDEO'];

function reqPermissionsFromUser(permissions: Array<Permissions>, context: common.UIAbilityContext): void {
  let atManager: abilityAccessCtrl.AtManager =
    abilityAccessCtrl.createAtManager();
  // requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗
  atManager.requestPermissionsFromUser(context, permissions).then((data) => {
    let grantStatus: Array<number> = data.authResults;
    let length: number = grantStatus.length;
    for (let i = 0; i < length; i++) {
      if (grantStatus[i] === 0) {
        // 用户授权,可以继续访问目标操作
      } else {
        // 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限
        return;
      }
    }
    // 授权成功
  }).catch((err: BusinessError) => {
    console.error(`Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`);
  })
}

aboutToAppear(): void {
  reqPermissionsFromUser(permissions, this.context)
}

步骤三:调用组件截图获取 pixelMap

/* 组件截图 */
clickToComponentSnapshot() {
  // root 为组件ID
  componentSnapshot.get("root", (error: Error, pixmap: image.PixelMap) => {
    if (error) {
      console.log("error: " + JSON.stringify(error))
      return;
    }
    console.log('截图成功')
    this.pixmap = pixmap
  })
}

步骤四:保存到系统相册或者应用沙箱

// 保存到系统相册
async savePixmap2SysHelper() {
  if (!this.pixmap) {
    return
  }
  const imgBuffer = await this.transferPixelMap2Buffer(this.pixmap)

  /*  获取相册管理模块的实例,用于访问和修改相册中的媒体文件。 */
  let helper = photoAccessHelper.getPhotoAccessHelper(getContext(this))

  /* 指定待创建的文件类型和后缀,创建图片或视频资源,使用callback方式返回结果。 */
  const uri = await helper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'png')
  const file = await fs.open(uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)
  await fs.write(file.fd, imgBuffer)
  /* 关闭文件 */
  await fs.close(file.fd)
}

/* 将 pixelMap 转成图片格式 */
transferPixelMap2Buffer(pixelMap: image.PixelMap): Promise<ArrayBuffer> {
  return new Promise((resolve, reject) => {
    /**
     设置打包参数
     format:图片打包格式,只支持 jpg 和 webp
     quality:JPEG 编码输出图片质量
     bufferSize:图片大小,默认 10M
   */
    let packOpts: image.PackingOption = { format: "image/jpeg", quality: 98 }
    // 创建ImagePacker实例
    const imagePackerApi = image.createImagePacker()
    imagePackerApi.packing(pixelMap, packOpts).then((buffer: ArrayBuffer) => {
      resolve(buffer)
    }).catch((err: BusinessError) => {
      reject()
    })
  })
}

/* 保存到应用沙箱 */
async savePixmal2SystemFileManager() {
  if (!this.pixmap) {
    return
  }
  const imgBuffer = await this.transferPixelMap2Buffer(this.pixmap)
  const file =
    fs.openSync(this.filesDir + `/${DateUtil.getTimeStamp()}.png`, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
  await fs.write(file.fd, imgBuffer)
  /* 关闭文件 */
  await fs.close(file.fd)
}

4、如何实现page页面的横竖屏切换?

使用setPreferredOrientation设置横竖屏切换:setPreferredOrientation

import { window } from '@kit.ArkUI';

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';
  private portrait: boolean = true
  changeOrientation = () => {
    // 获取当前页面
    let context = getContext(this)
    window.getLastWindow(context).then((mainWindow) => {
      this.changeOrientationInternal(mainWindow)
    }).catch((error: ESObject) => {
      console.log('getMainWindow error: ' + JSON.stringify(error))
    })
  }

  changeOrientationInternal(lastWindow: window.Window) {
    if (this.portrait) {
      // 切换成横屏
      lastWindow.setPreferredOrientation(window.Orientation.LANDSCAPE).then(() => {
        console.log('setPreferredOrientation success')
        this.portrait = !this.portrait
      }).catch((error: ESObject) => {
        console.log('setPreferredOrientation failure' + JSON.stringify(error))
      })
    } else {
      // 切换成竖屏
      lastWindow.setPreferredOrientation(window.Orientation.PORTRAIT).then(() => {
        console.log('setPreferredOrientation success')
        this.portrait = !this.portrait
      }).catch((error: ESObject) => {
        console.log('setPreferredOrientation failure: ' + JSON.stringify(error))
      })
    }
  }

  build() {
    Column() {
      Text(this.message)
        .id('Index19HelloWorld')
        .fontSize(50)
        .fontWeight(FontWeight.Bold)
        .alignRules({
          center: { anchor: '__container__', align: VerticalAlign.Center },
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })
      Button('横竖屏切换')
        .onClick(() => {
          this.changeOrientation()
        })
    }
    .height('100%')
    .width('100%')
    .backgroundColor(Color.Green)
  }}

5、如何实现防截屏功能?

1、设置窗口为隐私模式时,需要entry的module.json5文件中添加相关权限

2、使用setWindowPrivacyMode设置隐私模式

import { window } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct Index20 {
  @State message: string = 'Hello World';
  window?: window.Window;

  aboutToAppear(): void {
    window.getLastWindow(getContext(this)).then((mainWindow) => {
      this.setWindowPrivacyMode(mainWindow, true)
    }).catch((error: ESObject) => {
      console.log("getMainWindow error: " + JSON.stringify(error))
    })
  }

  setWindowPrivacyMode(windowClass: window.Window, isPrivacyMode: boolean) {
    try {
      // 设置窗口为隐私模式,窗口内容将无法被截屏或录屏。
      let promise = windowClass.setWindowPrivacyMode(isPrivacyMode);
      promise.then(() => {
        console.info('Succeeded in setting the window to privacy mode.');
      }).catch((err: BusinessError) => {
        console.error('Failed to set the window to privacy mode. Cause: ' + JSON.stringify(err));
      });

      console.info(`setWindowPrivacyMode 已执行`);
    } catch (exception) {
      console.error('Failed to set the window to the privacy mode. Cause:' + JSON.stringify(exception));
    }
  }

  build() {
    Column() {
      Text(this.message)
        .id('Index20HelloWorld')
        .fontSize(50)
        .fontWeight(FontWeight.Bold)
        .alignRules({
          center: { anchor: '__container__', align: VerticalAlign.Center },
          middle: { anchor: '__container__', align: HorizontalAlign.Center }
        })
    }
    .height('100%')
    .width('100%')
  }
}
相关推荐
HarmonyOS_SDK1 小时前
多样化消息通知样式,帮助应用提升日活跃度
harmonyos
塞尔维亚大汉3 小时前
【OpenHarmony】 鸿蒙矢量图形(SVG)之XmlGraphicsBatik
harmonyos·arkui
goodbruce4 小时前
HarmonyOS鸿蒙开发 MVVM模式及状态管理
harmonyos
轻口味7 小时前
【每日学点鸿蒙知识】Hap 安装失败、ArkTS 与C++ 数组转换、渐变遮罩效果等
c++·华为·harmonyos
SuperHeroWu77 小时前
【HarmonyOS】鸿蒙应用实现屏幕录制详解和源码
harmonyos·鸿蒙·视频·录屏·屏幕录制·沙箱·麦克风
轻口味8 小时前
【每日学点鸿蒙知识】一键登录、包资源分析工具、har包版本冲突、系统相册等
华为·harmonyos
法迪9 小时前
华为 Sensor 省电策略调研
华为·功耗
枫叶丹49 小时前
【HarmonyOS之旅】基于ArkTS开发(一) -> Ability开发一
ui·华为·harmonyos
星释10 小时前
鸿蒙Flutter实战:15-Flutter引擎Impeller鸿蒙化、性能优化与未来
flutter·harmonyos·鸿蒙
编程百晓君16 小时前
Harmony OS开发-ArkTS语言速成五
javascript·harmonyos·arkts