Skip to main content

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.

1

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ă.

easy_localization oferă extensii de context precum context.tr() și 'key'.tr(), pentru acces concis la traduceri. Gestionează încărcarea și păstrarea setării regionale, precum și reîncărcarea la cald a fișierelor de traducere în timpul dezvoltării.
pubspec.yaml
dependencies:
  easy_localization: ^3.0.7
  flutter_localizations:
    sdk: flutter
2

Creaț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.

assets/translations/en.arb
{
  "@@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"
      }
    }
  }
}
Cheile prefixate cu @ (precum @greeting) sunt metadate — acestea descriu șirul aflat deasupra lor. Includeți tipurile substituenților și exemple pentru a ajuta traducătorii să producă traduceri exacte. Aceste chei de metadate sunt eliminate în timpul execuției și nu adaugă niciun cost suplimentar.
3

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.

lib/main.dart
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(),
    );
  }
}
"Easy Localization not initialized" — această eroare înseamnă că ați omis să apelați EasyLocalization.ensureInitialized() înainte de runApp(). Apelul trebuie așteptat după WidgetsFlutterBinding.ensureInitialized() și înainte de runApp().
4

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')).

lib/widgets/home_page.dart
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)),
        ],
      ),
    );
  }
}
Dacă traducerile returnează cheile neprelucrate în locul textului tradus, verificați următoarele: 1) widgetul EasyLocalization încadrează MaterialApp, nu invers; 2) fișierele de traducere sunt declarate în pubspec.yaml, în secțiunea assets; 3) calea fișierelor din EasyLocalization corespunde structurii reale a directoarelor dumneavoastră.
5

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.

Plural forms by language
// 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} товаров}}"
Variables and named arguments
// 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}));
Nu codificați niciodată direct logica singular/plural folosind if (count == 1). Limbi precum franceza tratează 0 drept singular. Rusa, poloneza și araba au forme de plural care nu există deloc în engleză. Folosiți întotdeauna sintaxa ICU pentru plural și permiteți cadrului software să selecteze forma corectă.
6

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.

lib/widgets/adaptive_layout.dart
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,
          ),
        ],
      ),
    );
  }
}
RTL-aware widget patterns
// 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
Testați RTL setând temporar setarea regională a aplicației la arabă (Locale('ar')). Flutter oglindește întreaga interfață — sertarele de navigare se deschid din dreapta, săgețile de întoarcere își schimbă orientarea, iar textul se aliniază la dreapta. Folosiți EdgeInsetsDirectional, AlignmentDirectional și BorderRadiusDirectional pentru ca aspectele personalizate să fie oglindite corect.
7

Lanț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.

lib/main.dart with LocaleChain
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.
Custom fallback configuration
// 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
);
locale_chain include lanțuri de revenire predefinite pentru variantele regionale de portugheză, spaniolă, franceză, germană, italiană, neerlandeză, norvegiană și malaeză. Un utilizator pt-BR va vedea conținutul pt-PT înaintea celui în engleză. Un utilizator es-MX va vedea mai întâi es-419, apoi es și abia după aceea setarea regională implicită.
8

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.

Terminal
# 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
Traduceți incremental — când adăugați chei noi în fișierul ARB sursă, traduceți numai diferențele, fără să regenerați toate fișierele. Astfel, păstrați traducerile verificate de oameni și metadatele ARB intacte.

Automatizați verificarea calității traducerilor

Detectați cheile lipsă și substituenții nevalizi înainte de lansare cu i18n-validate. Testați interfața cu pseudotraduceri folosind i18n-pseudo înainte ca traducerile reale să fie disponibile.

Probleme frecvente

Fișierele de traducere nu sunt găsite în timpul execuției

Fișierele ARB/JSON trebuie declarate în pubspec.yaml, în secțiunea assets. Dacă omiteți acest pas, Flutter nu poate găsi fișierele în timpul execuției, chiar dacă acestea există pe disc. Adăugați: assets: - assets/translations/

Sintaxă nevalidă în fișierul ARB

Fișierele ARB folosesc JSON strict — fără virgule finale, ghilimele simple sau comentarii. O singură eroare de sintaxă împiedică discret încărcarea întregului fișier. Validați fișierele ARB cu un instrument de verificare JSON înainte de a depana problemele de traducere.

Modificările traducerilor nu apar după reîncărcarea la cald

easy_localization păstrează traducerile în memorie. Adăugarea unor chei noi sau modificarea traducerilor existente poate necesita o repornire completă la cald (hot restart), nu doar o reîncărcare la cald (hot reload). În timpul dezvoltării, folosiți hot restart (Shift+R) după editarea fișierelor de traducere.

Valorile stânga/dreapta codificate direct afectează RTL

Folosirea EdgeInsets.only(left: 16) în loc de EdgeInsetsDirectional.only(start: 16) împiedică Flutter să oglindească aspectul pentru limbile RTL. Căutați în baza de cod EdgeInsets, Alignment și BorderRadius fără sufixul Directional.

Structură recomandată a fișierelor

Project Structure
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ă

Nu este necesară înregistrareaEstimare instantanee

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.

Terminal
flutter pub add locale_chain
Configuration
import '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 →

Întrebări frecvente