
Flutter ローカライズ完全ガイド
ARB ファイルから RTL 対応まで、easy_localization で Flutter アプリをローカライズし、あらゆる言語の複数形を処理して、AI で翻訳を自動化します。
easy_localization のインストール
pubspec.yaml に easy_localization パッケージを追加します。ARB/JSON ファイル、複数形、コンテキスト拡張に対応する、最も広く利用されている Flutter i18n パッケージです。日付、数値、テキスト方向をロケールに応じて書式設定するため、SDK の flutter_localizations も追加してください。
dependencies:
easy_localization: ^3.0.7
flutter_localizations:
sdk: flutterARB 翻訳ファイルの作成
Application Resource Bundle(ARB)ファイルは、Flutter の標準的なローカライズ形式です。各ファイルにはキーと値のペアのほか、プレースホルダー、複数形規則、翻訳者向けの文脈を説明するオプションのメタデータが含まれます。assets/translations ディレクトリにロケールごとのファイルを 1 つ作成してください。
{
"@@locale": "en",
"appTitle": "My App",
"@appTitle": {
"description": "The title of the application"
},
"greeting": "Hello, {name}!",
"@greeting": {
"description": "Greeting with user name",
"placeholders": {
"name": {
"type": "String",
"example": "Alice"
}
}
},
"itemCount": "{count, plural, =0{No items} =1{1 item} other{{count} items}}",
"@itemCount": {
"description": "Number of items in the cart",
"placeholders": {
"count": {
"type": "num",
"format": "compact"
}
}
}
}アプリの設定
EasyLocalization ウィジェットでアプリをラップします。このウィジェットはロケール状態を管理し、アセットファイルから翻訳を読み込み、MaterialApp に必要なロケールデリゲートを提供します。必須の 3 つのデリゲートプロパティは localizationsDelegates、supportedLocales、locale で、すべてコンテキスト拡張から利用できます。
import 'package:flutter/material.dart';
import 'package:easy_localization/easy_localization.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized();
runApp(
EasyLocalization(
supportedLocales: [
Locale('en'),
Locale('ar'),
Locale('ja'),
Locale('de'),
],
path: 'assets/translations', // Path to your ARB/JSON files
fallbackLocale: Locale('en'),
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
localizationsDelegates: context.localizationDelegates,
supportedLocales: context.supportedLocales,
locale: context.locale,
home: HomePage(),
);
}
}ウィジェットの翻訳
任意のウィジェットで翻訳テキストを取得するには、文字列キーに .tr() 拡張メソッドを使用します。複数形には件数とともに .plural() を使用してください。easy_localization では、文字列拡張構文('key'.tr())とコンテキストメソッド構文(context.tr('key'))の両方を利用できます。
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('appTitle'.tr()), // Simple key
),
body: Column(
children: [
// String with variable interpolation
Text('greeting'.tr(args: ['Alice'])),
// Named arguments
Text('greeting'.tr(namedArgs: {'name': 'Alice'})),
// Plural form
Text('itemCount'.plural(3)),
],
),
);
}
}複数形と変数の処理
Flutter は、iOS、Android、Web と同じ標準規格である ICU MessageFormat を複数形に使用します。ARB ファイルで {count, plural, ...} 構文を使用して複数形を定義してください。CLDR 複数形規則に基づき、言語ごとに異なる形式が必要です。アラビア語は 6 形式、ロシア語は 4 形式、日本語は 1 形式です。
// English: 3 useful forms (=0, =1, other)
"itemCount": "{count, plural, =0{No items} =1{1 item} other{{count} items}}"
// Arabic: 6 forms (=0, =1, =2, few, many, other)
"itemCount": "{count, plural, =0{لا عناصر} =1{عنصر واحد} =2{عنصران} few{{count} عناصر} many{{count} عنصرًا} other{{count} عنصر}}"
// Japanese: 1 form (other)
"itemCount": "{count, plural, other{{count}個のアイテム}}"
// German: 2 forms (=1, other)
"itemCount": "{count, plural, =1{1 Artikel} other{{count} Artikel}}"
// Russian: 3 forms (one, few, many)
"itemCount": "{count, plural, =0{Нет товаров} one{{count} товар} few{{count} товара} many{{count} товаров} other{{count} товаров}}"// Simple variable
"welcome": "Welcome, {name}!"
// Multiple variables
"orderStatus": "Order #{orderId} — {status}"
// Variable in plural context
"unreadMessages": "{count, plural, =0{No unread messages} =1{1 unread message from {sender}} other{{count} unread messages}}"
// In widgets:
Text('welcome'.tr(namedArgs: {'name': userName}));
Text('orderStatus'.tr(namedArgs: {'orderId': '1234', 'status': 'Shipped'}));
Text('unreadMessages'.plural(count, namedArgs: {'sender': senderName}));RTL 言語への対応
ロケールがアラビア語、ヘブライ語、ペルシャ語、ウルドゥー語などの右から左へ記述する言語の場合、Flutter はレイアウト全体を自動的に反転します。ただし、正しく反転させるには、コードで方向に対応したウィジェットとプロパティを使用する必要があります。ハードコードした left/right を、対応する start/end に置き換えてください。
import 'package:flutter/material.dart';
class AdaptiveLayout extends StatelessWidget {
@override
Widget build(BuildContext context) {
final isRtl = Directionality.of(context) == TextDirection.rtl;
return Scaffold(
body: Row(
children: [
// Use start/end instead of left/right
Expanded(
child: Padding(
padding: EdgeInsetsDirectional.only(
start: 16.0, // Leading edge (left in LTR, right in RTL)
end: 8.0, // Trailing edge
),
child: Text('content'.tr()),
),
),
// Flip icons for RTL
Icon(
isRtl ? Icons.arrow_back : Icons.arrow_forward,
),
],
),
);
}
}// Use Directional widgets for RTL-aware layouts
EdgeInsetsDirectional.only(start: 16, end: 8) // Not EdgeInsets.only(left: 16, right: 8)
AlignmentDirectional.centerStart // Not Alignment.centerLeft
BorderRadiusDirectional.only(topStart: Radius.circular(8))
// Automatically mirrors when locale changes to Arabic, Hebrew, etc.
// No conditional logic needed — Flutter handles text direction from locale高度なロケールフォールバックチェーン
Flutter はデフォルトで、pt-BR 翻訳がない場合に適切な pt-PT 翻訳を飛ばし、英語へ直接フォールバックします。locale_chain パッケージは、設定可能なフォールバックチェーンでこの問題を修正します。設定は 1 行で、移行は不要です。既存の .tr() 呼び出しがそのまま動作します。
import 'package:locale_chain/locale_chain.dart';
import 'package:locale_chain/easy_localization.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await EasyLocalization.ensureInitialized();
LocaleChain.configure(); // Enable smart fallback chains
runApp(
EasyLocalization(
supportedLocales: [
Locale('en'),
Locale('pt', 'BR'),
Locale('pt', 'PT'),
Locale('es'),
Locale('es', 'MX'),
],
path: 'assets/translations',
assetLoader: LocaleChainAssetLoader( // Swap in the chain loader
baseLoader: RootBundleAssetLoader(),
),
fallbackLocale: Locale('en'),
child: MyApp(),
),
);
}
// Result: pt-BR user sees pt-PT translations when pt-BR keys are missing,
// instead of falling back directly to English.// Override specific chains while keeping built-in defaults
LocaleChain.configure(
fallbacks: {
'pt-BR': ['pt-PT', 'pt'], // pt-BR → pt-PT → pt → en
'es-MX': ['es-419', 'es'], // es-MX → es-419 → es → en
'fr-CA': ['fr'], // fr-CA → fr → en
},
);
// Or replace all defaults with your own chains
LocaleChain.configure(
fallbacks: {
'zh-Hant-HK': ['zh-Hant-TW', 'zh-Hans'],
'pt-BR': ['pt-PT', 'pt'],
},
mergeDefaults: false, // Only your chains, no built-in defaults
);翻訳の自動化
ローカライズの設定が完了したら、AI を使用して ARB ファイルを翻訳します。IDE で AI アシスタントにソース ARB ファイルの翻訳を依頼するか、CI/CD パイプラインで i18n Agent CLI を使用できます。プレースホルダーや説明などの ARB メタデータが文脈を提供し、翻訳品質を高めます。
# In your IDE, ask your AI assistant:
> Translate assets/translations/en.arb to Arabic, Japanese, and German
✓ ar.arb created (1.4s)
✓ ja.arb created (1.2s)
✓ de.arb created (1.1s)
# Or use the CLI in CI/CD:
npx i18n-agent translate assets/translations/en.arb --lang ar,ja,de翻訳品質の自動管理
よくある問題
実行時に翻訳ファイルが見つからない
ARB ファイルの構文が無効
ホットリロードで翻訳の変更が反映されない
ハードコードした left/right により RTL が崩れる
推奨ファイル構成
my_flutter_app/
├── assets/
│ └── translations/
│ ├── en.arb # Source language (English)
│ ├── ar.arb # Arabic (with 6 plural forms)
│ ├── de.arb # German
│ ├── ja.arb # Japanese
│ ├── pt-BR.arb # Brazilian Portuguese
│ └── pt-PT.arb # European Portuguese
├── lib/
│ ├── main.dart # App entry with EasyLocalization
│ ├── app.dart # MaterialApp with locale delegates
│ └── widgets/
│ └── language_switcher.dart
├── pubspec.yaml # Dependencies
└── analysis_options.yamli18n Agent を今すぐ試す
翻訳ファイルをここにドロップ
JSON, YAML, PO, XML, CSV, Markdown, Properties
またはクリックしてファイルを選択
翻訳先言語
locale_chain によるロケールフォールバック
pt-BR のような地域ロケールに翻訳キーがない場合、Flutter は親ロケール pt を先に確認せず、テンプレート言語へ直接フォールバックします。
flutter pub add locale_chainimport 'package:locale_chain/locale_chain.dart';
LocaleChain.configure(fallbacks: {
'pt-BR': ['pt', 'en'],
'zh-Hant-HK': ['zh-Hant', 'zh', 'en'],
});
LocaleChainAssetLoader(baseLoader: RootBundleAssetLoader());対応フレームワークの全一覧と 75 の組み込みチェーンについては、ロケールフォールバックガイドをご覧ください。 Learn more →