Flutter 国际化与本地化详解

文章总体概览信息图

一、国际化概述

Flutter 国际化(Internationalization)允许应用支持多种语言和地区。通过本地化(Localization),应用可以根据用户的语言偏好显示相应的内容。

1.1 基本概念

  • 国际化 (i18n) - 设计应用使其能够支持多种语言
  • 本地化 (l10n) - 为特定语言和地区提供资源
  • Locale - 语言和地区标识符(如 en_US、zh_CN)

二、配置国际化

2.1 添加依赖

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  intl: ^0.18.1

2.2 配置 MaterialApp

import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/intl.dart';

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter i18n Demo',
      localizationsDelegates: const [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
      supportedLocales: const [
        Locale('en', 'US'),
        Locale('zh', 'CN'),
        Locale('ja', 'JP'),
      ],
      home: const HomePage(),
    );
  }
}

三、创建本地化资源

3.1 创建 ARB 文件

// lib/l10n/app_en.arb
{
  "@@locale": "en",
  "helloWorld": "Hello World!",
  "welcome": "Welcome to our app",
  "greeting": "Hello {name}",
  "itemsCount": "{count} items"
}
// lib/l10n/app_zh.arb
{
  "@@locale": "zh",
  "helloWorld": "你好世界!",
  "welcome": "欢迎使用我们的应用",
  "greeting": "你好 {name}",
  "itemsCount": "{count} 个项目"
}

3.2 配置 pubspec.yaml

flutter:
  generate: true
  assets:
    - lib/l10n/

3.3 生成代码

flutter pub get

四、使用本地化字符串

4.1 基础用法

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

class HomePage extends StatelessWidget {
  const HomePage({super.key});

  @override
  Widget build(BuildContext context) {
    final loc = AppLocalizations.of(context)!;

    return Scaffold(
      appBar: AppBar(title: Text(loc.helloWorld)),
      body: Center(
        child: Column(
          children: [
            Text(loc.welcome),
            Text(loc.greeting('John')),
            Text(loc.itemsCount(5)),
          ],
        ),
      ),
    );
  }
}

4.2 复数处理

// app_en.arb
{
  "itemsCount": "{count, plural, zero {No items} one {One item} other {{count} items}}"
}
// app_zh.arb
{
  "itemsCount": "{count, plural, zero {没有项目} one {一个项目} other {{count} 个项目}}"
}

五、数字和日期格式化

5.1 数字格式化

final number = NumberFormat.decimalPattern(locale.languageCode);
print(number.format(12345.67));

5.2 日期格式化

final date = DateFormat.yMMMd(locale.languageCode);
print(date.format(DateTime.now()));

5.3 货币格式化

final currency = NumberFormat.currency(
  locale: locale.languageCode,
  symbol: '¥',
);
print(currency.format(100));

六、动态切换语言

6.1 创建状态管理

class LocaleProvider extends ChangeNotifier {
  Locale _locale = const Locale('en');

  Locale get locale => _locale;

  void setLocale(Locale locale) {
    _locale = locale;
    notifyListeners();
  }
}

6.2 使用状态管理

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (_) => LocaleProvider(),
      child: Consumer<LocaleProvider>(
        builder: (context, provider, child) {
          return MaterialApp(
            locale: provider.locale,
            localizationsDelegates: const [...],
            supportedLocales: const [...],
            home: const HomePage(),
          );
        },
      ),
    );
  }
}

6.3 切换语言

void _changeLanguage(BuildContext context, Locale locale) {
  Provider.of<LocaleProvider>(context, listen: false).setLocale(locale);
}

七、实战案例

7.1 语言选择器

class LanguageSelector extends StatelessWidget {
  const LanguageSelector({super.key});

  @override
  Widget build(BuildContext context) {
    return DropdownButton<Locale>(
      value: Provider.of<LocaleProvider>(context).locale,
      items: const [
        DropdownMenuItem(value: Locale('en'), child: Text('English')),
        DropdownMenuItem(value: Locale('zh'), child: Text('中文')),
        DropdownMenuItem(value: Locale('ja'), child: Text('日本語')),
      ],
      onChanged: (locale) {
        if (locale != null) {
          Provider.of<LocaleProvider>(context, listen: false).setLocale(locale);
        }
      },
    );
  }
}

八、总结

国际化与本地化步骤:

  1. 添加依赖 - flutter_localizations、intl
  2. 创建 ARB 文件 - 定义各语言字符串
  3. 配置 pubspec.yaml - 启用代码生成
  4. 生成代码 - flutter pub get
  5. 使用本地化字符串 - AppLocalizations.of(context)
  6. 格式化数字和日期 - NumberFormat、DateFormat
  7. 动态切换语言 - 使用状态管理

合理的国际化可以让应用支持更多用户。

更多推荐