
Ghidul complet pentru localizarea Flutter
De la fișiere ARB la compatibilitatea RTL: localizați-vă aplicația Flutter cu easy_localization, gestionați formele de plural pentru fiecare limbă și automatizați traducerile cu IA.
Instalați easy_localization
Adăugați pachetul easy_localization în pubspec.yaml. Acesta este cel mai popular pachet Flutter pentru i18n, compatibil cu fișiere ARB/JSON, forme de plural și extensii de context. Adăugați și flutter_localizations din SDK pentru formatarea datelor, numerelor și direcției textului în funcție de setarea regională.
dependencies:
easy_localization: ^3.0.7
flutter_localizations:
sdk: flutterCreați fișierele de traducere ARB
Fișierele Application Resource Bundle (ARB) reprezintă formatul standard de localizare pentru Flutter. Fiecare fișier conține perechi cheie-valoare și metadate opționale care descriu substituenții, regulile de plural și contextul destinat traducătorilor. Creați câte un fișier pentru fiecare setare regională în directorul assets/translations.
{
"@@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"
}
}
}
}Configurați aplicația
Încadrați aplicația în widgetul EasyLocalization. Acesta gestionează starea setării regionale, încarcă traducerile din fișierele de resurse și furnizează delegații de localizare necesari pentru MaterialApp. Cele trei proprietăți obligatorii ale delegaților sunt localizationsDelegates, supportedLocales și locale — toate fiind disponibile prin extensii de context.
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(),
);
}
}Traduceți widgeturile
Folosiți metoda de extensie .tr() pentru cheile șirurilor, ca să obțineți textul tradus în orice widget. Pentru formele de plural, folosiți .plural() împreună cu valoarea numerică. easy_localization oferă atât sintaxa extensiei pentru șiruri ('key'.tr()), cât și sintaxa metodei de context (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)),
],
),
);
}
}Gestionați formele de plural și variabilele
Flutter folosește ICU MessageFormat pentru formele de plural — același standard utilizat de iOS, Android și platformele web. Definiți formele de plural în fișierele ARB folosind sintaxa {count, plural, ...}. Fiecare limbă necesită propriul set de forme, stabilit de regulile de plural CLDR. Araba are 6 forme, rusa are 4, iar japoneza are 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}));Asigurați compatibilitatea cu limbile RTL
Flutter oglindește automat întregul aspect atunci când setarea regională corespunde unei limbi scrise de la dreapta la stânga (arabă, ebraică, persană sau urdu). Totuși, codul dumneavoastră trebuie să folosească widgeturi și proprietăți sensibile la direcție pentru ca oglindirea să funcționeze corect. Înlocuiți valorile fixe stânga/dreapta cu echivalentele început/sfârșit.
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 localeLanțuri inteligente de revenire pentru setările regionale
În mod implicit, când lipsește o traducere pt-BR, Flutter revine direct la engleză — ignorând traducerile pt-PT perfect utilizabile. Pachetul locale_chain remediază această problemă prin lanțuri de revenire configurabile. O singură linie de configurare, fără migrare — apelurile .tr() existente funcționează în continuare.
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
);Automatizați traducerile
După finalizarea configurării localizării, traduceți fișierele ARB cu ajutorul IA. În mediul dumneavoastră de dezvoltare, solicitați asistentului IA să traducă fișierul ARB sursă sau folosiți i18n Agent CLI în fluxul CI/CD. Metadatele ARB (substituenți și descrieri) oferă un context care îmbunătățește calitatea traducerii.
# 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,deAutomatizați verificarea calității traducerilor
Probleme frecvente
Fișierele de traducere nu sunt găsite în timpul execuției
Sintaxă nevalidă în fișierul ARB
Modificările traducerilor nu apar după reîncărcarea la cald
Valorile stânga/dreapta codificate direct afectează RTL
Structură recomandată a fișierelor
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.yamlÎncercați acum i18n Agent
Plasați aici fișierul de traducere
JSON, YAML, PO, XML, CSV, Markdown, Properties
sau faceți clic pentru a-l selecta
Limbi țintă
Revenirea la alte setări regionale cu locale_chain
Când lipsește o cheie de traducere într-o setare regională precum pt-BR, Flutter trece direct la limba șablonului în loc să verifice mai întâi setarea regională părinte 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());Consultați Ghidul nostru privind revenirea la alte setări regionale pentru lista completă a cadrelor software acceptate și a celor 75 de lanțuri încorporate. Learn more →