
Den komplette guide til Flutter-lokalisering
Fra ARB-filer til RTL-understøttelse: Lokaliser din Flutter-app med easy_localization, håndter flertalsformer for alle sprog og automatiser oversættelser med AI.
Installer easy_localization
Føj pakken easy_localization til din pubspec.yaml. Det er den mest populære Flutter i18n-pakke med understøttelse af ARB/JSON-filer, flertalsformer og context-udvidelser. Tilføj også flutter_localizations fra SDK'et for lokaletilpasset formatering af datoer, tal og tekstretning.
dependencies:
easy_localization: ^3.0.7
flutter_localizations:
sdk: flutterOpret ARB-oversættelsesfiler
Application Resource Bundle-filer (ARB) er standardformatet til lokalisering i Flutter. Hver fil indeholder nøgle-værdi-par med valgfri metadata, der beskriver pladsholdere, flertalsregler og kontekst til oversættere. Opret én fil pr. lokale i mappen 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"
}
}
}
}Konfigurer appen
Pak din app ind i EasyLocalization-widgetten. Den administrerer lokalets tilstand, indlæser oversættelser fra dine assetfiler og leverer de lokalisering-delegates, som MaterialApp skal bruge. De tre påkrævede delegate-egenskaber er localizationsDelegates, supportedLocales og locale — alle er tilgængelige via context-udvidelser.
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(),
);
}
}Oversæt widgets
Brug udvidelsesmetoden .tr() på strengnøgler for at hente oversat tekst i enhver widget. Brug .plural() med antalsværdien til flertalsformer. easy_localization understøtter både syntaksen med strengudvidelsen ('key'.tr()) og syntaksen med context-metoden (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)),
],
),
);
}
}Håndter flertalsformer og variabler
Flutter bruger ICU MessageFormat til flertalsformer — samme standard som iOS, Android og internettet. Definer flertalsformer med syntaksen {count, plural, ...} i dine ARB-filer. Hvert sprog kræver sit eget sæt former baseret på CLDR's flertalsregler. Arabisk har 6 former, russisk har 4 og japansk har 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}));Understøt RTL-sprog
Flutter spejler automatisk hele layoutet, når landestandarden bruger et sprog, der skrives fra højre mod venstre (arabisk, hebraisk, persisk eller urdu). Din kode skal dog bruge retningsbevidste widgets og egenskaber, for at spejlingen fungerer korrekt. Erstat hardkodet venstre/højre med tilsvarende start/slut-egenskaber.
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 localeIntelligente lokale fallbackkæder
Når en pt-BR-oversættelse mangler, går Flutter som standard direkte tilbage til engelsk og springer velfungerende pt-PT-oversættelser over. Pakken locale_chain løser dette med konfigurerbare fallbackkæder. Én opsætningslinje, ingen migrering — dine eksisterende .tr()-kald fungerer med det samme.
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
);Automatiser oversættelser
Når lokaliseringsopsætningen er færdig, kan du oversætte dine ARB-filer med AI. Bed din AI-assistent i IDE'et om at oversætte ARB-kildefilen eller brug i18n Agent CLI i din CI/CD-pipeline. ARB-metadata (pladsholdere og beskrivelser) giver kontekst, der forbedrer oversættelseskvaliteten.
# 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,deAutomatiser oversættelseskvaliteten
Almindelige faldgruber
Oversættelsesfiler blev ikke fundet ved kørsel
Ugyldig syntaks i ARB-filen
Oversættelsesændringer vises ikke efter hot reload
Hardkodet venstre/højre ødelægger RTL
Anbefalet filstruktur
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.yamlPrøv i18n Agent nu
Slip din oversættelsesfil her
JSON, YAML, PO, XML, CSV, Markdown, Properties
eller klik for at vælge en fil
Målsprog
Lokale fallback med locale_chain
Når en oversættelsesnøgle mangler i et regionalt lokale som pt-BR, går Flutter direkte til skabelonsproget i stedet for først at kontrollere det overordnede lokale 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());Se vores guide til lokale fallback for at få den komplette liste over understøttede frameworks og 75 indbyggede kæder. Learn more →