Skip to main content

Guia completa de localització amb Flutter

Des dels fitxers ARB fins a la compatibilitat amb RTL: localitzi la seva aplicació Flutter amb easy_localization, gestioni els plurals de cada idioma i automatitzi les traduccions amb IA.

1

Instal·lar easy_localization

Afegeixi el paquet easy_localization al fitxer pubspec.yaml. És el paquet d'i18n més popular per a Flutter i admet fitxers ARB/JSON, plurals i extensions de context. Afegeixi també flutter_localizations de l'SDK per aplicar formats de dates i nombres i una direcció del text adaptats a la configuració regional.

easy_localization proporciona extensions de context com context.tr() i 'key'.tr() per accedir a les traduccions de manera concisa. Gestiona la càrrega i la persistència de la configuració regional, així com la recàrrega en calent dels fitxers de traducció durant el desenvolupament.
pubspec.yaml
dependencies:
  easy_localization: ^3.0.7
  flutter_localizations:
    sdk: flutter
2

Crear fitxers de traducció ARB

Els fitxers Application Resource Bundle (ARB) són el format de localització estàndard de Flutter. Cada fitxer conté parelles de clau i valor amb metadades opcionals que descriuen els marcadors de posició, les regles de plural i el context per als traductors. Creï un fitxer per configuració regional al directori 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"
      }
    }
  }
}
Les claus amb el prefix @ (com ara @greeting) són metadades: descriuen la cadena que tenen a sobre. Inclogui els tipus de marcadors de posició i exemples per ajudar els traductors a produir traduccions precises. Aquestes claus de metadades s'eliminen durant l'execució i no comporten cap sobrecàrrega.
3

Configurar l'aplicació

Embolcalli l'aplicació amb el giny EasyLocalization. Gestiona l'estat de la configuració regional, carrega les traduccions dels fitxers de recursos i proporciona els delegats de configuració regional que necessita MaterialApp. Les tres propietats de delegació obligatòries són localizationsDelegates, supportedLocales i locale, totes disponibles mitjançant extensions 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": aquest error vol dir que no ha cridat EasyLocalization.ensureInitialized() abans de runApp(). Cal esperar-ne el resultat després de WidgetsFlutterBinding.ensureInitialized() i abans de runApp().
4

Traduir ginys

Utilitzi el mètode d'extensió .tr() amb les claus de cadena per obtenir text traduït en qualsevol giny. Per als plurals, utilitzi .plural() amb el valor del recompte. easy_localization proporciona tant la sintaxi d'extensió de cadena ('key'.tr()) com la sintaxi del mètode 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)),
        ],
      ),
    );
  }
}
Si les traduccions retornen les claus sense traduir en comptes del text traduït, comprovi: 1) Que el giny EasyLocalization embolcalli MaterialApp i no a l'inrevés. 2) Que els fitxers de traducció estiguin declarats a pubspec.yaml dins d'assets. 3) Que el camí del fitxer a EasyLocalization coincideixi amb l'estructura real de directoris.
5

Gestionar plurals i variables

Flutter utilitza ICU MessageFormat per als plurals, el mateix estàndard que fan servir iOS, Android i el web. Defineixi les formes plurals amb la sintaxi {count, plural, ...} als fitxers ARB. Cada idioma necessita el seu propi conjunt de formes segons les regles de plural de CLDR. L'àrab en té 6, el rus 4 i el japonès 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}));
No codifiqui mai directament la lògica de singular i plural amb if (count == 1). Idiomes com el francès tracten el 0 com a singular. El rus, el polonès i l'àrab tenen formes plurals que no existeixen en anglès. Utilitzi sempre la sintaxi de plural d'ICU i deixi que el framework seleccioni la forma correcta.
6

Admetre idiomes RTL

Flutter reflecteix automàticament tota la disposició quan la configuració regional correspon a un idioma escrit de dreta a esquerra (àrab, hebreu, persa o urdú). Tanmateix, perquè la reflexió funcioni correctament, el codi ha d'utilitzar ginys i propietats que tinguin en compte la direcció. Substitueixi els valors esquerra/dreta codificats directament pels equivalents inici/final.

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
Provi l'RTL establint temporalment la configuració regional de l'aplicació en àrab (Locale('ar')). Flutter reflecteix tota la interfície: els calaixos de navegació s'obren des de la dreta, les fletxes de retrocés s'inverteixen i el text s'alinea a la dreta. Utilitzi EdgeInsetsDirectional, AlignmentDirectional i BorderRadiusDirectional per assegurar-se que les disposicions personalitzades es reflecteixin correctament.
7

Cadenes intel·ligents de configuracions regionals de reserva

Per defecte, quan falta una traducció pt-BR, Flutter recorre directament a l'anglès i omet traduccions pt-PT perfectament vàlides. El paquet locale_chain ho resol amb cadenes de reserva de configuracions regionals configurables. Només cal una línia de configuració i no cal cap migració: les crides .tr() existents continuen funcionant.

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 inclou cadenes de reserva integrades per a les variants regionals del portuguès, l'espanyol, el francès, l'alemany, l'italià, el neerlandès, el noruec i el malai. Un usuari pt-BR veurà el contingut pt-PT abans que l'anglès. Un usuari es-MX veurà es-419 i després es abans de la configuració regional predeterminada.
8

Automatitzar les traduccions

Un cop completada la configuració de localització, tradueixi els fitxers ARB amb IA. Demani a l'assistent d'IA del seu IDE que tradueixi el fitxer ARB d'origen o utilitzi la CLI d'i18n Agent al pipeline de CI/CD. Les metadades ARB (marcadors de posició i descripcions) proporcionen context i milloren la qualitat de la traducció.

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
Tradueixi de manera incremental: quan afegeixi claus noves al fitxer ARB d'origen, tradueixi només les diferències en comptes de tornar a generar tots els fitxers. Així conservarà les traduccions revisades per persones i mantindrà intactes les metadades ARB.

Automatitzar la qualitat de les traduccions

Detecti les claus absents i els marcadors de posició malmesos abans del llançament amb i18n-validate. Provi la interfície amb pseudotraduccions mitjançant i18n-pseudo abans que arribin les traduccions reals.

Errors habituals

No es troben els fitxers de traducció durant l'execució

Cal declarar els fitxers ARB/JSON a pubspec.yaml dins de la secció assets. Si omet aquest pas, Flutter no podrà trobar els fitxers durant l'execució, encara que existeixin al disc. Afegeixi: assets: - assets/translations/

Sintaxi de fitxer ARB no vàlida

Els fitxers ARB són JSON estricte: no admeten comes finals, cometes simples ni comentaris. Un sol error de sintaxi impedeix silenciosament que es carregui tot el fitxer. Validi els fitxers ARB amb un verificador de sintaxi JSON abans de depurar problemes de traducció.

Els canvis de traducció no apareixen amb la recàrrega en calent

easy_localization desa les traduccions a la memòria cau. Perquè l'addició de claus noves o els canvis en traduccions existents tinguin efecte, pot caldre un reinici en calent complet, no una recàrrega en calent. Durant el desenvolupament, utilitzi el reinici en calent (Shift+R) després d'editar els fitxers de traducció.

Els valors esquerra/dreta codificats directament trenquen l'RTL

Utilitzar EdgeInsets.only(left: 16) en comptes d'EdgeInsetsDirectional.only(start: 16) impedeix que Flutter reflecteixi la disposició per als idiomes RTL. Cerqui EdgeInsets, Alignment i BorderRadius sense el sufix Directional al codi font.

Estructura de fitxers recomanada

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

Provar i18n Agent ara

Arrossegar aquí el fitxer de traducció

JSON, YAML, PO, XML, CSV, Markdown, Properties

o fer clic per explorar

Idiomes de destinació

No cal registrePressupost instantani

configuracions regionals de reserva amb locale_chain

Quan falta una clau de traducció en una configuració regional com pt-BR, Flutter salta directament a l'idioma de la plantilla en comptes de comprovar primer la configuració regional superior 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());

Consulti la nostra guia de configuracions regionals de reserva per veure la llista completa de frameworks compatibles i les 75 cadenes integrades. Learn more →

Preguntes freqüents