HarmonyOS NextにおけるArkUI基本コンポーネントの実践ガイド

レイアウト設計の基礎と応用

ArkUIでは、画面構成は「コンポーネントの組み合わせ」として実現されます。適切なレイアウトを選択することで、視覚的にも操作的にも優れたインターフェースが構築可能です。

レイアウトの構造理解

  • 青領域:要素の物理的なサイズ(widthheightで設定)
  • 黄領域:実際の描画可能範囲(青領域 - ボーダー値)
  • 緑領域:コンテンツの本質的なサイズ(例:テキストの自動拡張)
  • 破線領域:マージンを含む全体的な影響範囲

主要レイアウトコンポーネントの使い分け

コンポーネント 使用シーン サンプルコード
Row / Column 直列配置が必要な場合(複数要素) Row() { Text('商品1'); Text('商品2'); }
Stack 重ね合わせ(例:ボタン上にアイコン) Stack() { Image('star'); Button('いいね') }
Flex 比率に基づく自動調整 Flex({ direction: 'row' }) { Text('A').flexGrow(1); Text('B').flexGrow(2); }
RelativeContainer 複雑な2次元配置(ネスト回避) RelativeContainer() { Image().position({ x: 50, y: 30 }); Text('名前') }
List スクロール可能な長リスト(チャット履歴など) List({ data: messages }) { Item(() => Text(item.text)) }

位置制御の技法

// 絶対位置指定(親要素の左上を原点)
Component().position({ x: 40, y: 60 })

// 相対移動(自身の元位置からのずれ)
Component().offset({ x: 10, y: -5 })

子要素の制御戦略

効果 プロパティ
拡張 flexGrow, flexShrink Text('伸縮').flexGrow(1)
アスペクト比維持 aspectRatio Image().aspectRatio(1.8)
表示優先度 displayPriority Button().displayPriority(3)

実用的なベストプラクティス

  • width('70%')で割合指定が可能だが、親コンポーネントのサイズが明確である必要あり
  • layoutWeightを使って空きスペースを自動分配
  • デバイスごとのレイアウト切り替え:
    if (mediaQuery.matchDevice({ orientation: 'landscape' })) {
      buildRowLayout();
    } else {
      buildColumnLayout();
    }

画像処理の高度な技術

Imageコンポーネントの活用法

PNG/JPG/SVG/GIF等をサポートし、多様な表示が可能。

// 基本的な画像表示
Image($r('app.media.logo'))
Image('https://example.com/banner.jpg')
Image('images/icon.png')

画像の読み込みモード

種別 用途
リソース引用 共通画像の再利用 Image($r('app.media.icon'))
ネットワーク画像 動的コンテンツ Image('https://.../avatar.jpg')
メディアライブラリ ユーザー選択画像 Image('file://media/Photos/1')
Base64埋め込み 小規模画像内蔵 Image('data:image/png;base64,...')

矢量画像のカスタマイズ

// SVGの色変更
Image($r('app.media.sun'))
  .fillColor(Color.Yellow)
  .width(60)

画像のスタイル調整

  • objectFit:表示モード(ContainCoverFill
  • objectRepeat:パターン繰り返し(XYXY
  • colorFilter:フィルター効果(レトロ・モノクロなど)

パフォーマンス最適化

  • 解像度制限:.sourceSize({ width: 150, height: 150 })
  • 補間品質:.interpolation(ImageInterpolation.High)
  • 同期読み込み:.syncLoad(true)(注意:非同期が推奨)

イベントハンドリング

Image('banner.jpg')
  .onComplete((msg) => {
    console.log(`画像サイズ: ${msg.width}x${msg.height}`);
  })
  .onError(() => {
    console.log('画像読込失敗');
  })

テキスト表示とインタラクション

TextとSpanの使い分け

  • Text:独立した段落やタイトル
  • SpanText内での部分的スタイル適用
Text('これは') {
  Span('赤文字').decoration({
    type: TextDecorationType.LineThrough,
    color: Color.Red
  })
  Span('青下線').decoration({
    type: TextDecorationType.Underline,
    color: Color.Blue
  })
}

テキストスタイルのカスタム

  • textAlign:左・中央・右揃え
  • maxLinestextOverflow:省略表示(EllipsisMarquee
  • textCase:大文字/小文字変換
  • letterSpacing:字間調整
  • baselineOffset:基線位置変更

インタラクティブなテキスト

Text('クリック可能')
  .onClick(() => {
    console.log('タップされた');
  })

Text() {
  Span('リンク風').onClick(() => {
    router.pushUrl({ url: 'pages/detail' });
  })
}

アクセシビリティ対応

Text('重要通知')
  .accessibilityDescription('システム更新に関する緊急情報です')

入力欄の完全マニュアル

TextInput vs TextArea

  • TextInput:単一行入力(ログインフォームなど)
  • TextArea:複数行入力(コメント欄など)
TextInput({ placeholder: 'メールアドレス' })
  .type(InputType.Email)

TextArea({ text: '詳細説明...' }).maxLength(500)

入力タイプの選択

タイプ 用途
Password パスワード入力(マスク表示) .type(InputType.Password)
Number 数字専用キーボード .type(InputType.Number)
PhoneNumber 電話番号入力 .type(InputType.PhoneNumber)

キーボード遮蔽対策

Scroll() {
  Column() {
    ForEach(messages, (msg) => {
      TextArea({ text: msg.content })
        .margin(10)
    })
  }
}

ボタンのデザインとインタラクション

ボタンの種類

  • ButtonType.Capsule:カプセル型(丸み固定)
  • ButtonType.Circle:完全な円形
  • ButtonType.Normal:自由な角丸設定

スタイルのカスタマイズ

// 渐变背景
Button('VIP特典')
  .linearGradient({
    angle: 45,
    colors: [[0xff00ff, 0], [0x00ffff, 1]]
  })

// シャドウ付き
Button('新着')
  .shadow({ radius: 8, color: Color.Gray })

クリックイベントと安全対策

let isSubmitting = false;

Button('送信')
  .onClick(() => {
    if (isSubmitting) return;
    isSubmitting = true;
    // API呼び出し
    setTimeout(() => { isSubmitting = false; }, 1500);
  })

特殊な使い方

  • 長押しによるコピーアクション:.onLongPress(() => clipboard.copy(...))
  • 振動フィードバック:.onTouch(event => if (event.type === TouchType.Down) vibrator.vibrate(30))
  • ロード中状態:Button({ type: ButtonType.Normal }) { LoadingProgress().width(20); Text('処理中...') }

タグ: HarmonyOS ArkUI ETS UI Layout Image

8月11日 07:50 投稿