Mobiludvikling med Flutter · Lektion

Flertalsformer, køn og ICU-meddelelsesformatering

Håndtér flertalsformer, select-tilfælde og parametriserede strenge med ICU-meddelelsessyntaksen.

Lektion 2 af 413 trin

Flertalsformer, køn og ICU-meddelelsesformatering er en gratis Mobiludvikling med Flutter-lektion på CoddyKit. Dette er lektion 2 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i Mobiludvikling med Flutter, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Mobiludvikling med Flutter-kurset indeholder 4 lektioner i alt.

Hvorfor ICU-meddelelser er vigtige

At oversætte en app handler om mere end at udskifte ord. Forskellige sprog bøjer ord i flertal, bruger grammatisk køn og ordner ord forskelligt. En naiv streng som "$count items" ser forkert ud som "1 items", og mange sprog har flere flertalsformer.

Flutter løser dette med ICU-meddelelsessyntaks (International Components for Unicode), den samme standard, der bruges i hele branchen. Du skriver én meddelelse med regler for flertal, valg/køn og pladsholdere, hvorefter den rigtige form vælges under kørsel for hver lokalitet.

  • plural — vælg en form baseret på et tal
  • select — vælg en gren baseret på en streng (f.eks. køn)
  • pladsholdere — indsæt værdier med typer, f.eks. navne, datoer og tal

ARB-filen: Her bor meddelelserne

Flutters værktøjskæde med flutter_localizations + intl læser ARB-filer (Application Resource Bundle). Hver lokalitet har sin egen fil: app_en.arb, app_tr.arb osv.

En ARB-post har en nøgle, en værdi (ICU-meddelelsen) og et valgfrit metadataobjekt med @key, der beskriver pladsholdere.

  • Nøgler bliver til genererede Dart-gettere/metoder.
  • Blokken @key angiver hver pladsholders type og valgfri format.
{
  "appTitle": "My Shop",
  "@appTitle": {
    "description": "The title shown in the app bar"
  },
  "welcome": "Welcome, {name}!",
  "@welcome": {
    "placeholders": {
      "name": { "type": "String" }
    }
  }
}

Enkle pladsholdere

En pladsholder skrives i krøllede parenteser inde i meddelelsen: {name}. Den genererede Dart-kode bliver til en metode, hvis parameter svarer til pladsholderens navn.

Når du har aktiveret generate: true i pubspec.yaml og kørt flutter gen-l10n, kalder du den via AppLocalizations.

// app_en.arb
//   "welcome": "Welcome, {name}!"

import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

Widget build(BuildContext context) {
  final l10n = AppLocalizations.of(context)!;
  return Text(l10n.welcome('Aylin')); // -> "Welcome, Aylin!"
}

Flertalsbøjning med ICU

Formen plural vælger en gren baseret på et talargument. Syntaks: {count, plural, ...categories...}.

ICU's flertalskategorier er =0, =1, zero, one, two, few, many, other. Grenen other er obligatorisk — den bruges som reserve, når ingen anden kategori passer. Brug # til at udskrive selve tallet.

  • =0 og =1 matcher den nøjagtige værdi.
  • one, few og many er sprogspecifikke kategorier (engelsk bruger kun one og other).
{
  "itemsInCart": "{count, plural, =0{Your cart is empty} =1{1 item in cart} other{# items in cart}}",
  "@itemsInCart": {
    "placeholders": {
      "count": { "type": "int" }
    }
  }
}

Kald af en flertalsmeddelelse

Den genererede metode tager tælleargumentet. Programrammen vælger automatisk den rigtige gren for den aktive lokalitet.

Bemærk, at engelsk kun har brug for one/other, mens en lokalitet som polsk eller arabisk bruger few/many i sin egen ARB-fil — dit Dart-kaldested ændres ikke.

final l10n = AppLocalizations.of(context)!;

Text(l10n.itemsInCart(0));  // "Your cart is empty"
Text(l10n.itemsInCart(1));  // "1 item in cart"
Text(l10n.itemsInCart(7));  // "7 items in cart"

Hvorfor '=1' og 'one' er forskellige

En almindelig forveksling er, at =1 er et match på en nøjagtig værdi, mens one er en sprogspecifik flertalskategori. De er ikke det samme.

  • =1 matcher kun det bogstavelige tal 1.
  • one matcher det, som lokalitetens CLDR-regler kalder kategorien "one". På engelsk er det kun 1, men i nogle lokaliteter omfatter kategorien one også værdier som 21, 31 osv.

Bedste praksis er altid at angive other, tilføje one for naturligt ental/flertal og kun bruge =0/=1, når du har brug for en særlig formulering ("tom", "ingen meddelelser"), der adskiller sig fra det grammatiske flertal.

Køn og formen 'select'

Formen select opdeler efter en streng i stedet for et tal. Den klassiske anvendelse er grammatisk køn, som ændrer stedord og overensstemmelse mellem udsagnsord og grundled på mange sprog.

Syntaks: {gender, select, male{...} female{...} other{...}}. Ligesom ved flertal er other påkrævet som reserve og håndterer ukendte værdier og værdier uden for tokønssystemet på en robust måde.

{
  "sharedPhoto": "{gender, select, male{He shared a photo} female{She shared a photo} other{They shared a photo}}",
  "@sharedPhoto": {
    "placeholders": {
      "gender": { "type": "String" }
    }
  }
}

Demonstration af select() i ren Dart

Du behøver ikke Flutter for at forstå intl-primitiverne. Funktionen Intl.select afspejler det, den genererede kode gør: Den knytter en nøgle til en gren med en other-reserve.

Dette selvstændige program viser valogikken, herunder reserven, når der kommer en uventet værdi.

import 'package:intl/intl.dart';

String sharedPhoto(String gender) {
  return Intl.select(gender, {
    'male': 'He shared a photo',
    'female': 'She shared a photo',
    'other': 'They shared a photo',
  }, name: 'sharedPhoto', args: [gender]);
}

void main() {
  print(sharedPhoto('male'));    // He shared a photo
  print(sharedPhoto('female'));  // She shared a photo
  print(sharedPhoto('unknown')); // They shared a photo (fallback)
}

Kombination af køn og flertal (indlejring)

ICU lader dig indlejre et flertal i et valg (eller omvendt), så du kan håndtere meddelelser, der varierer efter både køn og antal. Placér den ene blok i en gren af den anden.

Hold indlejringen enkel — dybt indlejrede meddelelser er besværlige for oversættere. Hvis det bliver komplekst, kan du overveje at opdele det i separate nøgler.

{
  "likes": "{gender, select, female{She got {count, plural, =0{no likes} =1{1 like} other{# likes}}} male{He got {count, plural, =0{no likes} =1{1 like} other{# likes}}} other{They got {count, plural, =0{no likes} =1{1 like} other{# likes}}}}",
  "@likes": {
    "placeholders": {
      "gender": { "type": "String" },
      "count": { "type": "int" }
    }
  }
}

Formaterede pladsholdere: Tal og datoer

Pladsholdere kan formateres pr. lokalitet ved hjælp af feltet format i metadataene. Tal bruger formater som decimalPattern eller currency, mens datoer bruger DateFormat-skabeloner som yMMMd.

Det betyder, at 1234.5 automatisk vises som 1,234.5 i en-US, men som 1.234,5 i mange europæiske lokaliteter.

{
  "price": "Total: {amount}",
  "@price": {
    "placeholders": {
      "amount": {
        "type": "double",
        "format": "currency",
        "optionalParameters": { "symbol": "\u20ac", "decimalDigits": 2 }
      }
    }
  },
  "lastSeen": "Last seen {when}",
  "@lastSeen": {
    "placeholders": {
      "when": { "type": "DateTime", "format": "yMMMd" }
    }
  }
}

Formatering af tal og datoer i ren Dart

De samme intl-formateringsfunktioner driver ARB-felterne format. Her er et kørbart program, der bruger NumberFormat og DateFormat direkte, sådan som den genererede lokaliseringskode gør internt.

import 'package:intl/intl.dart';

void main() {
  final amount = 1234.5;
  final usd = NumberFormat.currency(locale: 'en_US', symbol: '\$');
  final eur = NumberFormat.currency(locale: 'de_DE', symbol: '\u20ac');

  print(usd.format(amount)); // \$1,234.50
  print(eur.format(amount)); // 1.234,50 \u20ac

  final date = DateTime(2026, 6, 10);
  print(DateFormat.yMMMd('en_US').format(date)); // Jun 10, 2026
  print(DateFormat.yMMMd('tr_TR').format(date)); // 10 Haz 2026
}

Hurtigt tjek: Vælg den rigtige form

Du skal bruge en meddelelse, der siger "ingen meddelelser", "1 meddelelse" eller "N meddelelser" afhængigt af et antal, og den skal også fungere korrekt i lokaliteter med kategorierne few/many. Hvilken fremgangsmåde er korrekt?

Opsamling

Du ved nu, hvordan du lokaliserer dynamisk tekst i Flutter med ICU-meddelelsessyntaks:

  • ARB-filer indeholder meddelelser pr. lokalitet; metadata med @key angiver pladsholdernes typer og formater.
  • Pladsholdere som {name} indsætter værdier med typer i meddelelser.
  • plural {count, plural, =0{} =1{} other{}} vælger en form efter tallet; other er obligatorisk, og # udskriver værdien.
  • =1 kontra one: match på nøjagtig værdi kontra sprogspecifik flertalskategori — brug kun nøjagtige match til særlige formuleringer.
  • select {gender, select, male{} female{} other{}} opdeler efter en streng og er velegnet til køn.
  • Indlejring kombinerer køn og antal, når det er nødvendigt.
  • Metadata med format samt NumberFormat/DateFormat viser tal og datoer efter lokalitet.

Skriv meddelelserne, så oversætterne kan styre formuleringen på hvert sprog, mens dine Dart-kaldesteder forbliver uændrede.

Gratis at komme i gang

Lær Dart med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
22
Lektioner
88

Ofte stillede spørgsmål

Er lektionen “Flertalsformer, køn og ICU-meddelelsesformatering” gratis?

Ja — alle 3 lektioner i læringssporet Mobiludvikling med Flutter, inklusive “Flertalsformer, køn og ICU-meddelelsesformatering”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Mobiludvikling med Flutter-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Flertalsformer, køn og ICU-meddelelsesformatering”?

Håndtér flertalsformer, select-tilfælde og parametriserede strenge med ICU-meddelelsessyntaksen. Du øver dig i Mobiludvikling med Flutter med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Mobiludvikling med Flutter?

Der kræves ingen tidligere erfaring. Mobiludvikling med Flutter på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 2 af 4.

Hvor lang tid tager lektionen “Flertalsformer, køn og ICU-meddelelsesformatering”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Mobiludvikling med Flutter-lektion?

Ja. Alle Mobiludvikling med Flutter-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. ARB-filer og lokaliseringsworkflow med gen_l10n
  2. Flertalsformer, køn og ICU-meddelelsesformatering
  3. RTL-layouts og håndtering af retning
  4. Semantics, skærmlæsere og tilgængelige widgets
← Tilbage til Mobiludvikling med Flutter