1. PasteButton 是什么?

PasteButton 是 ArkUI 中的一个 安全控件,专门用来做「安全粘贴」:

  • 用户点击 PasteButton
  • 系统弹出安全授权逻辑;
  • 应用在 授权通过后,临时获取剪贴板读取权限,再去拿真实的剪贴板内容。

这样设计是为了防止应用「静默」读取剪贴板,保护用户隐私。

基础信息:

  • 组件名PasteButton

  • 类型:安全控件(不走普通 Button 的授权模型)

  • 子组件:不支持添加子组件(即内部不能嵌 Text / Image)

  • 支持版本

    • API 10 开始支持
    • API 11 起支持元服务(元服务API)

2. 快速上手:两种创建方式

PasteButton 有两种构造方式:

2.1 默认构造:PasteButton()

PasteButton()
  • 默认自带 图标 + 文本 + 背景
  • 默认 icon:PasteIconStyle.LINES(线条风格图标);
  • 默认文本:PasteDescription.PASTE(「粘贴」);
  • 默认背景类型:ButtonType.Capsule(胶囊按钮)。

这是最简单也最推荐的用法,适合大多数场景。


2.2 带配置构造:PasteButton(options)

PasteButton(options: PasteButtonOptions)

PasteButtonOptions 主要用来指定三样东西:

interface PasteButtonOptions {
  icon?: PasteIconStyle
  text?: PasteDescription
  buttonType?: ButtonType
}

约束要点:

  • icontext 至少传一个
  • 都不传options 整体无效,相当于 PasteButton() 默认样式;
  • 不传 buttonType:系统默认 ButtonType.Capsule
  • 这三个属性 都不支持动态修改,只能在构造时指定。

小结一张表:

字段 类型 说明
icon PasteIconStyle 粘贴按钮的图标风格,不传则无图标
text PasteDescription 文本描述,不传则无文本
buttonType ButtonType 按钮背景样式,缺省为 Capsule

3. 相关枚举:图标 / 文案 / 授权结果

3.1 PasteIconStyle:图标风格

enum PasteIconStyle {
  LINES = 0  // 线条风格的粘贴图标
}

目前只有一种风格,但通过背景 / 布局搭配,视觉上已经足够。


3.2 PasteDescription:默认文字

enum PasteDescription {
  PASTE = 0   // 文本为 “粘贴”
}

如果你的应用是中文语境,直接用默认 PASTE 一般就够了;
如果要国际化,可以配合多语言资源和按钮周边文案做整体设计(PasteButton 本身的枚举是固定的)。


3.3 PasteButtonOnClickResult:授权结果

enum PasteButtonOnClickResult {
  SUCCESS = 0,                    // 授权成功
  TEMPORARY_AUTHORIZATION_FAILED = 1  // 授权失败
}

onClick 回调里,你需要先看 result 是成功还是失败,只有成功时才去读剪贴板。


4. 点击回调:PasteButtonCallback 与 onClick

4.1 回调类型(API 18+)

type PasteButtonCallback = (
  event: ClickEvent,
  result: PasteButtonOnClickResult,
  error?: BusinessError<void>
) => void

参数含义:

  • event:点击事件对象(坐标、来源等,一般很少用到);
  • result:粘贴按钮授权结果(SUCCESS / TEMPORARY_AUTHORIZATION_FAILED);
  • error(可选):BusinessError<void>,里面包含 codemessage

版本差异说明:

  • API 10–17:onClick 的签名是 (event: ClickEvent, result: PasteButtonOnClickResult) => void
  • 从 API 18 起:统一使用 PasteButtonCallback,多了一个可选 error 参数。

4.2 error.code 含义(API 18+)

error 存在时,主要有几类情况:

  • 0:点击控件授权成功;

  • 1:系统内部错误;

  • 2属性设置错误,常见原因包括但不限于:

    1. 字体或图标太小;
    2. 字体 / 图标颜色和背景颜色太接近,对比度不够;
    3. 颜色过于透明(比如 alpha 太小);
    4. padding 设置为负值;
    5. 按钮被其他组件或窗口遮挡;
    6. 文本超出按钮背托范围;
    7. 按钮整体超出窗口 / 屏幕;
    8. 按钮整体尺寸过大;
    9. 按钮文本被截断显示不全;
    10. 其它会影响安全控件可见性 / 可点击性的属性设置。

这一条非常关键:
安全控件的外观必须清晰可见、可点击、文本完整,否则系统会认为有安全风险,不给授权。

4.3 onClick 使用方式

onClick(event: PasteButtonCallback)

PasteButton 不支持通用事件,只暴露 onClick

  • 点击按钮 → 触发回调;
  • 回调里根据 result / error 决定是否读取剪贴板、是否提示用户。

5. 基础示例:最简单的 PasteButton 用法

img

下面这个示例基本对应官方文档的写法,做了少量注释,适合直接丢 Demo 工程里跑:

// xxx.ets
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct PasteButtonBasicSample {
  handlePasteButtonClick: PasteButtonCallback =
    (event: ClickEvent, result: PasteButtonOnClickResult, error?: BusinessError<void>) => {
      if (result === PasteButtonOnClickResult.SUCCESS) {
        console.info('Paste authorize success');
        // TODO:这里调用剪贴板接口读取内容,再根据业务处理
        // 例如将剪贴板内容填入某个 TextInput
      } else {
        console.error('Paste authorize failed, errCode: ' + (error?.code ?? 'unknown'));
        console.error('errMessage: ' + (error?.message ?? ''));
      }
    };

  build() {
    Row() {
      Column({ space: 10 }) {
        // 1. 默认样式:图标 + 文本 + 背景
        PasteButton()
          .onClick(this.handlePasteButtonClick)

        // 2. 只传 icon,不传 text:只显示图标(和背景)
        // (未传 buttonType,系统会默认加上 Capsule 背景)
        PasteButton({ icon: PasteIconStyle.LINES })

        // 3. icon + 背景,自定义背景色(alpha 过低会被系统矫正)
        PasteButton({ icon: PasteIconStyle.LINES, buttonType: ButtonType.Capsule })
          // 若 alpha < 0x1A,系统会强制调整为 0xFF,保证可见性
          .backgroundColor(0x10007dff as number)

        // 4. icon + 文本 + 背景,完整样式
        PasteButton({
          icon: PasteIconStyle.LINES,
          text: PasteDescription.PASTE,
          buttonType: ButtonType.Capsule
        })

        // 5. icon + 文本 + 背景,宽度过小:文本会自动换行保证完整显示
        PasteButton({
          icon: PasteIconStyle.LINES,
          text: PasteDescription.PASTE,
          buttonType: ButtonType.Capsule
        })
          .fontSize(16)
          .width(30)

        // 6. 用 size 约束宽高的情况
        PasteButton({
          icon: PasteIconStyle.LINES,
          text: PasteDescription.PASTE,
          buttonType: ButtonType.Capsule
        })
          .fontSize(16)
          .size({ width: 30, height: 30 })

        // 7. 用 constraintSize 约束尺寸区间的情况
        PasteButton({
          icon: PasteIconStyle.LINES,
          text: PasteDescription.PASTE,
          buttonType: ButtonType.Capsule
        })
          .fontSize(16)
          .constraintSize({
            minWidth: 0,
            maxWidth: 30,
            minHeight: 0,
            maxHeight: 30
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

这个例子基本覆盖了:

  • 默认样式;
  • 仅图标样式;
  • 改背景色 / 改大小之后系统是如何「帮你兜底」的。

6. 实战示例:把 PasteButton 接到输入框里

下面写一个典型业务场景:
安全粘贴到 TextInput,比如在「账号绑定 / 邀请码输入 / 验证码」界面,用 PasteButton 做安全粘贴按钮。

img

这里不强绑定具体剪贴板 API,只做一个合理的结构,剪贴板调用你可以按自己项目的实际写。

// xxx.ets
import { BusinessError } from '@kit.BasicServicesKit';

@Entry
@Component
struct PasteIntoInputSample {
  @State inputValue: string = '';

  // 点击 PasteButton 的回调
  handlePasteClick: PasteButtonCallback =
    (event: ClickEvent, result: PasteButtonOnClickResult, error?: BusinessError<void>) => {
      if (result === PasteButtonOnClickResult.SUCCESS) {
        console.info('Paste authorize success');

        // TODO:在这里读取剪贴板内容,并更新 inputValue
        // 伪代码示例:
        // clipboard.getPrimaryClip().then((data) => {
        //   const text = data?.text ?? '';
        //   this.inputValue = text;
        // }).catch(err => {
        //   console.error('read clipboard failed: ' + err);
        // });

      } else {
        console.error('Paste authorize failed, code: ' + (error?.code ?? 'unknown'));
        // 可以根据 error.code 给用户一个轻提示,比如:
        // 1 = 系统内部错误;2 = 样式不合法导致授权失败
      }
    }

  build() {
    Column({ space: 12 }) {
      Text('请输入邀请码(支持安全粘贴)')
        .fontSize(16)
        .fontWeight(FontWeight.Medium)
        .margin({ bottom: 8 })

      Row({ space: 8 }) {
        TextInput({
          text: this.inputValue,
          placeholder: '点击右侧按钮粘贴'
        })
          .width('70%')
          .height(40)
          .onChange(value => this.inputValue = value)

        PasteButton({
          icon: PasteIconStyle.LINES,
          text: PasteDescription.PASTE,
          buttonType: ButtonType.Capsule
        })
          .onClick(this.handlePasteClick)
      }
      .width('90%')
      .alignItems(VerticalAlign.Center)
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
    .alignItems(HorizontalAlign.Center)
  }
}

你可以很方便地改造成:

  • 「粘贴手机号」、「粘贴地址」、「粘贴 token」等;
  • 甚至做成通用组件:把 onPasteSuccess(text: string) 作为入参传出去。

7. 安全控件样式约束:这几个坑别踩

PasteButton 属于 安全控件,样式是有「合规要求」的——
否则系统判断用户可能被「误导」或者按钮处于不可见状态,就会拒绝授权,导致 TEMPORARY_AUTHORIZATION_FAILEDerror.code = 2

可以理解为:你是在做一个系统级「敏感操作」按钮,必须让它看起来合理

常见约束总结如下:

  1. 文字 / 图标要足够大

    • 太小的字号 / 图标会影响可读性;
    • 系统可能判定为不合法样式。
  2. 颜色对比度要够

    • 文本 / 图标颜色不能和背景颜色太接近;
    • 不能太透明(例如背景色 alpha 过小,系统会将 alpha 强制调高到 0xFF)。
  3. padding 不要设成负值

    • 安全控件需要清晰的点击区域;
    • 负 padding 可能导致可视 & 可点区域异常。
  4. 按钮不能被遮挡

    • 被其他组件覆盖;
    • 被其它窗口压住,
      都会影响授权。
  5. 文本不能被截断 / 超框

    • 文本要完整展示在按钮背景范围内;
    • 当你设置太小的宽度时,系统会自动换行帮你保留完整显示。
  6. 按钮不能超出窗口 / 屏幕

    • 需要保证完整可见;
    • 尺寸不要随便设置成「全屏超大」,也不要一半跑到屏幕外面去。
  7. 整体尺寸要合理

    • 太大 / 太小都会影响用户感知;
    • 出问题时结合 error.code 与日志排查样式配置。

实战建议:开发阶段可以故意改一些「极限样式」,看是否会触发 error=2,
把所有可疑原因都在 console 里打印出来,方便团队后续踩坑就绕开。


8. 版本差异 & 使用建议

在工程里使用 PasteButton 时,建议注意以下几点:

  1. API 版本

    • PasteButton 最低支持:API 10
    • 回调签名在 API 18 有变化,多了 error 参数;
    • 如果你的应用需要兼容 10–18,可以自己封一层适配,让业务只关心「成功 / 失败」。
  2. 元服务 / 卡片

    • PasteButton 从 API 11 起支持元服务 API;
    • 在卡片 / 服务场景里使用时,要注意当前环境对安全控件的支持程度(有些效果可能仰赖上层框架)。
  3. 授权是「临时的」

    • 点击 PasteButton 获取的是 临时 剪贴板读取权限;
    • 最常见用法:在一次点击回调中,读取一次剪贴板并立即用掉。
  4. 不要把 PasteButton 当普通 Button 用

    • 它的职责是「用户明确发起粘贴」,不要拿来做别的业务按钮;
    • 其它操作仍然用普通 Button / TextButton 等组件。
Logo

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

更多推荐