当前位置: 首页 > article >正文

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

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%')
  }
}

http://www.kler.cn/a/465744.html

相关文章:

  • 机器人对物体重定向操作的发展简述
  • MySQL 索引分类及区别与特点
  • 【光纤通信】光纤结构
  • windows终端conda activate命令行不显示环境名
  • Trimble天宝X9三维扫描仪为建筑外墙检测提供了全新的解决方案【沪敖3D】
  • 2025/1/4期末复习 密码学 按老师指点大纲复习
  • oceanbase 集群启动操作
  • 【2025最新计算机毕业设计】基于SSM的物流管理系统(高质量源码,提供文档,免费部署到本地)【提供源码+答辩PPT+文档+项目部署】
  • termux配置nginx+php
  • C++函数模板的定义为何要和调用点放在一起
  • 【HAProxy】如何在Ubuntu下配置HAProxy服务器
  • 网站访问接口顺序执行,防止频繁请求接口而报错,处理切换功能时,必须先请求完数据才可执行下一个功能接口(2025-1-3)
  • GPU加速计算的专业云服务平台:蓝耘GPU算力平台的概述、具体应用与教学
  • Swift Combine 学习(六):自定义 Publisher 和 Subscriber
  • 基于STM32F103的USART的原理及应用(一)(实现手机BLE和MCU进行通信)
  • 探索Wiki:开源知识管理平台及其私有化部署
  • 手机租赁平台开发实用指南与市场趋势分析
  • 探索 Android Instant Apps:InstantAppInfo 的深入解析与架构设计
  • C++中关于异常的简单分析
  • C# 设计模式概况
  • Python爬虫入门(1)
  • 【Patroni官方文档】介绍与目录
  • 【谷歌开发者月刊】十二月精彩资讯回顾,探索科技新可能
  • 【C++】穿越时光隧道,拾贝史海遗珍,轻启C++入门之钥,解锁程序之奥秘(首卷)
  • 随机种子定不死找bug
  • python 字符串算法