Skip to main content

Täydellinen opas Flutter:in lokalisointiin

ARB-tiedostoista RTL-tukeen: lokalisoi Flutter-sovelluksesi easy_localization:illa, käsittele kaikkien kielten monikkomuodot ja automatisoi käännökset tekoälyllä.

1

Asenna easy_localization

Lisää easy_localization-paketti pubspec.yaml-tiedostoosi. Se on suosituin Flutter:in i18n-paketti ja tukee ARB- ja JSON-tiedostoja, monikkomuotoja sekä context-laajennuksia. Lisää SDK:sta myös flutter_localizations päivämäärien, lukujen ja tekstin suunnan kieliversiokohtaiseen muotoiluun.

easy_localization tarjoaa lyhyisiin käännöshakuihin context-laajennukset, kuten context.tr() ja 'key'.tr(). Se käsittelee kieliversioiden lataamisen, säilytyksen ja käännöstiedostojen kuumalatauksen kehityksen aikana.
pubspec.yaml
dependencies:
  easy_localization: ^3.0.7
  flutter_localizations:
    sdk: flutter
2

Luo ARB-käännöstiedostot

Application Resource Bundle (ARB) -tiedostot ovat Flutter:in vakiomuotoinen lokalisointimuoto. Kukin tiedosto sisältää avain-arvopareja ja valinnaisia metatietoja, jotka kuvaavat kääntäjille paikkamerkit, monikkosäännöt ja asiayhteyden. Luo yksi tiedosto kieliversiota kohden assets/translations-hakemistoon.

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"
      }
    }
  }
}
@-etuliitteiset avaimet, kuten @greeting, ovat metatietoja — ne kuvaavat yläpuolellaan olevaa merkkijonoa. Lisää paikkamerkkien tyypit ja esimerkit, jotta kääntäjät voivat tuottaa täsmällisiä käännöksiä. Metatietoavaimet poistetaan suorituksen aikana, joten ne eivät aiheuta kuormaa.
3

Määritä sovellus

Ympäröi sovelluksesi EasyLocalization-pienoisohjelmalla. Se hallitsee kieliversion tilaa, lataa käännökset resurssitiedostoistasi ja tarjoaa MaterialAppin tarvitsemat kieliversiodelegaatit. Kolme pakollista delegaattiominaisuutta ovat localizationsDelegates, supportedLocales ja locale, ja ne kaikki ovat saatavilla context-laajennuksilla.

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(),
    );
  }
}
Virhe "Easy Localization not initialized" tarkoittaa, että unohdit kutsua EasyLocalization.ensureInitialized()-funktiota ennen runApp()-funktiota. Sitä on odotettava WidgetsFlutterBinding.ensureInitialized()-funktion jälkeen ja ennen runApp()-funktiota.
4

Käännä pienoisohjelmat

Hae käännetty teksti missä tahansa pienoisohjelmassa käyttämällä merkkijonoavainten .tr()-laajennusmetodia. Käytä monikkomuotoihin .plural()-metodia ja määräarvoa. easy_localization tarjoaa sekä merkkijonolaajennussyntaksin ('key'.tr()) että context-metodisyntaksin (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)),
        ],
      ),
    );
  }
}
Jos käännökset palauttavat käännetyn tekstin sijaan käsittelemättömiä avaimia, tarkista seuraavat: 1) EasyLocalization-pienoisohjelma ympäröi MaterialAppin eikä päinvastoin. 2) Käännöstiedostosi on ilmoitettu pubspec.yaml-tiedoston assets-kohdassa. 3) EasyLocalizationin tiedostopolku vastaa todellista hakemistorakennettasi.
5

Käsittele monikkomuodot ja muuttujat

Flutter käyttää monikkomuotoihin ICU MessageFormat:ia, samaa standardia kuin iOS, Android ja verkko. Määritä monikkomuodot ARB-tiedostoissa {count, plural, ...}-syntaksilla. Kukin kieli tarvitsee omat CLDR-monikkosääntöihin perustuvat muotonsa. Arabiassa on kuusi muotoa, venäjässä neljä ja japanissa yksi.

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}));
Älä koskaan kovakoodaa yksikkö- tai monikkologiikkaa ehdolla if (count == 1). Ranskan kaltaisissa kielissä 0 käsitellään yksikkönä. Venäjässä, puolassa ja arabiassa on monikkomuotoja, joita englannissa ei ole lainkaan. Käytä aina ICU-monikkosyntaksia ja anna ohjelmistokehyksen valita oikea muoto.
6

Tue RTL-kieliä

Flutter peilaa koko asettelun automaattisesti, kun kieliversio kirjoitetaan oikealta vasemmalle (arabia, heprea, persia, urdu). Koodisi on kuitenkin käytettävä suunnan huomioivia pienoisohjelmia ja ominaisuuksia, jotta peilaus toimii oikein. Korvaa kovakoodatut left/right-arvot start/end-vastineilla.

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
Testaa RTL:ää asettamalla sovelluksesi kieliversioksi väliaikaisesti arabia (Locale('ar')). Flutter peilaa koko käyttöliittymän — siirtymislaatikot avautuvat oikealta, takaisin-nuolet kääntyvät ja teksti tasaantuu oikealle. Varmista mukautettujen asettelujen oikea peilaus EdgeInsetsDirectionalin, AlignmentDirectionalin ja BorderRadiusDirectionalin avulla.
7

Älykkäät varakieliketjut

Kun pt-BR-käännös puuttuu, Flutter siirtyy oletusarvoisesti suoraan englantiin ja ohittaa täysin käyttökelpoiset pt-PT-käännökset. locale_chain-paketti korjaa tämän määritettävillä varakieliketjuilla. Yksi rivi käyttöönottoon, ei siirtoa — nykyiset .tr()-kutsusi toimivat sellaisinaan.

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 sisältää sisäänrakennetut varakieliketjut portugalin, espanjan, ranskan, saksan, italian, hollannin, norjan ja malaijin alueellisille muodoille. pt-BR-käyttäjä näkee pt-PT-sisällön ennen englantia. es-MX-käyttäjä näkee es-419:n ja sitten es:n ennen oletuskieliversiota.
8

Automatisoi käännökset

Kun lokalisointi on otettu käyttöön, käännä ARB-tiedostosi tekoälyllä. Pyydä IDE-ympäristössäsi tekoälyavustajaasi kääntämään ARB-lähdetiedosto tai käytä i18n Agent:in CLI:tä CI/CD-putkessasi. ARB-metatiedot (paikkamerkit, kuvaukset) antavat asiayhteyttä ja parantavat käännösten laatua.

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
Käännä vaiheittain — kun lisäät uusia avaimia ARB-lähdetiedostoon, käännä vain diff äläkä luo kaikkia tiedostoja uudelleen. Näin ihmisten tarkistamat käännökset ja ARB-metatiedot säilyvät.

Automatisoi käännöslaatu

Löydä puuttuvat avaimet ja rikkoutuneet paikkamerkit i18n-validate:lla ennen julkaisua. Testaa käyttöliittymää pseudokäännöksillä i18n-pseudo:n avulla ennen oikeiden käännösten valmistumista.

Tavalliset sudenkuopat

Käännöstiedostoja ei löydy suorituksen aikana

ARB- tai JSON-tiedostosi on ilmoitettava pubspec.yaml-tiedoston assets-kohdassa. Jos vaihe puuttuu, Flutter ei löydä tiedostoja suorituksen aikana, vaikka ne olisivat levyllä. Lisää: assets: - assets/translations/

Virheellinen ARB-tiedoston syntaksi

ARB-tiedostot ovat tiukkaa JSON:ia — ei lopun pilkkuja, heittomerkkejä tai kommentteja. Yksi syntaksivirhe estää koko tiedoston lataamisen huomaamatta. Validoi ARB-tiedostot JSON-tarkistimella ennen käännösongelmien virheenjäljitystä.

Käännösmuutokset eivät näy kuumalatauksella

easy_localization tallentaa käännökset välimuistiin. Uusien avainten lisääminen tai nykyisten käännösten muuttaminen voi vaatia täydellisen kuumakäynnistyksen eikä vain kuumalatausta. Käytä kehityksen aikana käännöstiedostojen muokkaamisen jälkeen kuumakäynnistystä (Shift+R).

Kovakoodatut vasen/oikea-arvot rikkovat RTL:n

EdgeInsets.only(left: 16) -arvon käyttäminen EdgeInsetsDirectional.only(start: 16) -arvon sijaan estää Flutter:ia peilaamasta asetteluasi RTL-kielille. Etsi koodikannastasi EdgeInsets-, Alignment- ja BorderRadius-arvot ilman Directional-päätettä.

Suositeltu tiedostorakenne

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

Kokeile i18n Agent:ia nyt

Pudota käännöstiedostosi tähän

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

tai valitse napsauttamalla

Kohdekielet

Rekisteröitymistä ei tarvitaVälitön arvio

Varakieliketju locale_chain:illa

Kun alueellisesta kieliversiosta, kuten pt-BR:stä, puuttuu käännösavain, Flutter siirtyy suoraan mallin kieleen eikä tarkista ensin pääkieliversiota 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());

Katso varakielioppaastamme kaikki tuetut ohjelmistokehykset ja 75 sisäänrakennettua ketjua. Learn more →

Usein kysytyt kysymykset