HarmonyOSにおけるカスタム検証コード入力コンポーネントの実装

入力値の検証とフォーカス制御

入力値の長さが1文字以下であることを確認し、該当する位置のcodeArrayに値を格納します。これにより各入力フィールドが単一文字のみを受け付けるようにします。

次の入力フィールドが存在するか(現在のindex + 1がcodeArrayの長さより小さいか)を確認します。存在する場合、自動的に次の入力フィールドにフォーカスを移動させ、ユーザーが連続して入力できるようにします。

次の入力フィールドが存在しない場合、inputCompleteCallback関数を呼び出し、入力値を親コンポーネントや呼び出し元に渡します。

キー属性の設定

各TextInputコンポーネントにkey属性を追加し、focusController.requestFocusが正しくトリガーされるようにします。ここではindexを使用して一意のキーを生成します。

発生した問題と解決策

1. 初期フォーカスの欠如

初期表示時にどの入力フィールドにもフォーカスが設定されません。以下のコードをTextInputに追加することで解決します:

.defaultFocus(index == 0)

2. 削除操作時のonChange非トリガー

現在のバージョンでは削除操作がonChangeメソッドをトリガーしません。onKeyEventを使用した代替案も期待通り動作しませんでした。

3. ソフトキーボードの表示異常

requestFocusを使用して次の入力フィールドにフォーカスを移動すると、ソフトキーボードが閉じてしまいます。現在のTextInputコンポーネントでは完全な解決が難しいため、別のアプローチを採用します。

代替アプローチ:Text() + TextInput()の組み合わせ

複数の入力フィールドで問題が発生するため、単一のTextInputと複数のTextコンポーネントを組み合わせた解決策を提案します。

@Component
struct VerificationCodeInput {
  @State codeArray: string[] = new Array(5).fill('')
  inputCompleteCallback: (string) => void
  private inputId = "verification_input"
  @State showCursor: boolean = true

  build() {
    Stack() {
      Row({ space: vp(10) }) {
        ForEach(this.codeArray, (char: string, idx: number) => {
          Text(char)
            .backgroundColor($r('app.color.white_80'))
            .fontSize(fp(25))
            .textAlign(TextAlign.Center)
            .borderRadius(vp(15))
        })
      }

      TextInput()
        .maxLength(this.codeArray.length)
        .key(this.inputId)
        .onChange((inputValue) => {
          const chars = inputValue.split('')
          this.codeArray.forEach((_, pos) => {
            this.codeArray[pos] = chars[pos] || ''
          })
          if (chars.length >= this.codeArray.length) {
            this.inputCompleteCallback(inputValue)
          }
          this.showCursor = (chars.length === 0)
        })
        .fontColor(Color.Transparent)
        .backgroundColor(Color.Transparent)
        .caretColor(this.showCursor ? Color.Black : Color.Transparent)
    }
    .height(vp(80))
  }
}

実装のポイント

  1. TextInputをレイアウト全体に広げ、最前面に配置します
  2. 文字色と背景色を透明に設定して入力フィールドを隠します
  3. 対応する数のTextコンポーネントを表示用に配置します
  4. onChange内で入力文字列を分割し、各位置の配列に格納します

コンポーネントの使用方法

VerificationCodeInput({
  inputCompleteCallback: (code) => {
    // 検証コードの処理を実装
  }
})

カスタマイズの拡張

入力フィールドの幅、高さ、角丸、色、入力タイプ、数量などのパラメータをオブジェクトにまとめ、@Stateで修飾することで、柔軟なカスタマイズが可能になります。

タグ: HarmonyOS ArkUI TextInput Component TypeScript

6月4日 19:30 投稿