博客 / 詳情

返回

HarmonyOS ArkTS 組件進階 - PasteButton 自學指南

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 用法

image.png

下面這個示例基本對應官方文檔的寫法,做了少量註釋,適合直接丟 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 做安全粘貼按鈕。

image.png

這裏不強綁定具體剪貼板 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 等組件。
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.