flutter-setup-localization について
Flutter 開発者向けのローカライズ設定スキルです。ARB ファイルとコード生成による多言語テキスト管理に加え、ICU メッセージ形式、RTL レイアウト、導入手順を説明します。
主な機能
- 01Flutter のローカライズ依存関係の設定
- 02ARB ファイルとメタデータの整理
- 03プレースホルダー、複数形、選択形式の処理
- 04RTL 方向へのレイアウト対応
- 05ローカライズコードの生成と組み込み
活用シーン
- 01Flutter アプリへの多言語対応の追加
- 02引数や複数形を含む翻訳の管理
- 03アラビア語やヘブライ語向け画面の調整
- 04ローカライズ設定とコード生成の確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ dhruvanbhalara/ skills --skill flutter-setup-localizationインストール後、Claude Code で/flutter-setup-localizationを入力して読み込まれたか確認します。
詳細
目次
セットアップと設定
Flutter は flutter_localizations パッケージと intl パッケージを使用して国際化を処理します。標準的なワークフローでは、.arb ソースファイルを合成生成パッケージにコンパイルし、型安全なコードアクセスを実現します。
1. 依存関係の追加
ターミナルで以下のコマンドを実行し、必要な依存関係を pubspec.yaml に追加します:
flutter pub add flutter_localizations --sdk=flutter
flutter pub add intl:any
2. コード生成の有効化
pubspec.yaml ファイルの flutter セクション内で generate フラグを有効にします:
flutter:
generate: true
3. 設定ファイルの作成
プロジェクトのルートに l10n.yaml ファイルを作成し、ローカライズされたディレクトリの入出力を定義します:
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
synthetic-package: true
4. アプリケーションのエントリポイントの設定
生成された合成パッケージをインポートし、デリゲートとサポート対象のロケールを MaterialApp または CupertinoApp に注入します:
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
// ... inside the MaterialApp build method
return MaterialApp(
localizationsDelegates: const [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: const [
Locale('en'), // English
Locale('es'), // Spanish
],
home: const HomeScreen(),
);
ARB ファイルの構造とルール
App Resource Bundle(.arb)ファイルは、標準的な JSON フォーマットを使用してキーと値の翻訳文字列を表現します。
- ファイル命名:すべての ARB ファイルは
lib/l10n/内にapp_{locale}.arbパターン(例:app_en.arb、app_es.arb)で配置します。 - メタデータの要件:テンプレートファイル(
app_en.arb)には、すべての翻訳キーに対応する@keyメタデータオブジェクトを含める必要があり、翻訳ワークフローを支援する明確な説明を提供します。 - キー命名規則:
camelCaseまたは snake_case を一貫して使用します(例:loginTitleまたはlogin_title)。文字列がどこで使用されるかを示す、クリーンで説明的な名前を維持します。 - ユーザー向け文字列の厳格な分離:プレゼンテーション層でユーザー向け文字列をハードコーディングすることを禁止します。すべてのテキストは ARB キーを通じて公開します。
ICU メッセージフォーマット
ARB ファイル内で ICU メッセージ構文を使用し、動的引数、数量ベースの複数形、条件付き選択を処理します。
1. シンプルなプレースホルダー
パラメータ名を波括弧内で定義し、その型をキーメタデータ内に記述します:
"helloUser": "Hello {name}",
"@helloUser": {
"description": "Greeting message containing user name",
"placeholders": {
"name": {
"type": "String",
"example": "Jane"
}
}
}
2. 複数形
複数形構文を使用して、数えられる項目のバリエーションを定義します。other ケースは厳密に必須です:
"itemsCount": "{count, plural, =0{no items} =1{1 item} other{{count} items}}",
"@itemsCount": {
"description": "Inventory count message",
"placeholders": {
"count": {
"type": "num"
}
}
}
3. 選択
select 構文を使用して、引数の一致(例:enum のような値)に応じて文字列を表示します:
"pronoun": "{gender, select, male{he} female{she} other{they}}",
"@pronoun": {
"description": "Gendered pronoun selector",
"placeholders": {
"gender": {
"type": "String"
}
}
}
RTL(右から左)レイアウトのサポート
RTL 言語(例:アラビア語、ヘブライ語)向けにローカライズする場合、レイアウトは自動的に適応する必要があります:
- 方向性のある UI:
Directionalityと、書き込み方向を自動的に解決するウィジェットを使用します。 - 方向性のあるスペーシング:左右の絶対座標を決して使用しないでください。常に方向性のある同等のマージンとパディングを優先します(例:
EdgeInsets.only(left: 16)の代わりにEdgeInsetsDirectional.only(start: 16))。 - Flex 配置:
MainAxisAlignmentおよびCrossAxisAlignmentの flex レイアウト設定では、絶対的なleftやrightの値ではなく、startとendを優先します。
ワークフロー: ローカライズ対応の追加
多言語対応を実装および拡張するには、次のチェックリストに従ってください:
- パッケージを追加:
flutter_localizationsパッケージとintlパッケージをインストールします。 - 生成を有効化:
pubspec.yamlのgenerate: trueフラグをオンにします。 - l10n を設定: プロジェクトのルートに
l10n.yamlを作成します。 - テンプレートを作成: ベースラインとなるキーと説明を含む
lib/l10n/app_en.arbを作成します。 - 対象の翻訳を追加: 翻訳済みの文字列を含む
lib/l10n/app_es.arb(およびその他の対象言語ファイル)を作成します。 - コードを生成:
flutter pub getまたはflutter gen-l10nを実行してコンパイルをトリガーします。 - Delegate を注入:
MaterialAppを更新してローカライズ delegate を定義します。 - context ショートカットを公開: ウィジェット内で文字列をクリーンに解決するための、簡潔な context 拡張ヘルパーを追加します:
extension LocalizedContext on BuildContext { AppLocalizations get l10n => AppLocalizations.of(this)!; } - レイアウトの境界をテスト: 対象の RTL/LTR ロケールでテストを実行し、レイアウトと配置がエレガントに保たれることを確認します。
例
完全なベース ARB テンプレート (lib/l10n/app_en.arb)
{
"loginHeader": "Welcome Back",
"@loginHeader": {
"description": "Main header visible on the authentication screen"
},
"greetingMessage": "Welcome, {username}!",
"@greetingMessage": {
"description": "Personalized welcome greeting",
"placeholders": {
"username": {
"type": "String",
"example": "Jane"
}
}
},
"cartItems": "{count, plural, =0{Your cart is empty} =1{1 item in your cart} other{{count} items in your cart}}",
"@cartItems": {
"description": "Cart items indicator showing quantity status",
"placeholders": {
"count": {
"type": "num"
}
}
}
}
context コンシューマーウィジェット
この例では、カスタムの BuildContext 拡張ヘルパーを使用して、ローカライズされた値をクリーンに利用します。
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
// 1. Clean BuildContext extension helper
extension LocalizedContext on BuildContext {
AppLocalizations get l10n => AppLocalizations.of(this)!;
}
class DashboardHeader extends StatelessWidget {
final String username;
final int itemsCount;
const DashboardHeader({
super.key,
required this.username,
required this.itemsCount,
});
@override
Widget build(BuildContext context) {
// 2. Consume values cleanly via the extension shortcut
final l10n = context.l10n;
return Padding(
padding: const EdgeInsetsDirectional.only(start: 16.0, end: 16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
l10n.loginHeader,
style: Theme.of(context).textTheme.headlineMedium,
),
const SizedBox(height: 8),
Text(
l10n.greetingMessage(username),
style: Theme.of(context).textTheme.bodyLarge,
),
const SizedBox(height: 12),
Text(
l10n.cartItems(itemsCount),
style: Theme.of(context).textTheme.bodyMedium,
),
],
),
);
}
}