Flutterアプリを多言語化する


Published on May 20, 2020

Flutterアプリを多言語化する方法についての自分メモ

基本的にFlutter公式Documentに沿って。

対応言語は英語、日本語。

intlパッケージ導入版で進めます。


packageの追加


pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:    sdk: flutter
dev_dependencies:
  flutter_test:
    sdk: flutter
  intl_translation: ^0.17.09

intl_translation: ^0.17.10が最新ですが、下記エラーが出るため0.17.09を導入します。

Because intl_translation >=0.17.10 depends on petitparser ^3.0.0 and every version of flutter_test from sdk depends on petitparser 2.4.0, intl_translation >=0.17.10 is incompatible with flutter_test from sdk.


多言語化用のクラスを作成


l10nフォルダを作成し、l10n.dartにクラスを実装します。

lib/l10n/l10n.dart
import 'package:flutter/widgets.dart';
import 'package:intl/intl.dart';
import 'messages_all.dart';

class L10n {
  L10n(this.localeName);

  static Future<L10n> load(Locale locale) {
    final name =
        locale.countryCode.isEmpty ? locale.languageCode : locale.toString();
    final localeName = Intl.canonicalizedLocale(name);
    return initializeMessages(localeName).then((_) {
      return L10n(localeName);
    });
  }

  static L10n of(BuildContext context) {
    return Localizations.of<L10n>(context, L10n);
  }

  final String localeName;

  String get title {
    return Intl.message(
      'Hello World',
      name: 'title',
      desc: 'Title for the Demo application',
      locale: localeName,
    );
  }
}

class L10nDelegate extends LocalizationsDelegate<L10n> {
  const L10nDelegate();

  
  bool isSupported(Locale locale) => ['en', 'ja'].contains(locale.languageCode);

  
  Future<L10n> load(Locale locale) => L10n.load(locale);

  
  bool shouldReload(L10nDelegate old) => false;
}

initializeMessagesの部分でエラーが出ますが、次で解消します。


messages_all.dartの生成


terminal
$ flutter pub run intl_translation:extract_to_arb \
    --locale=messages \
    --output-dir=lib/l10n \
    lib/l10n/l10n.dart

intl_messages.arbが生成されます。

続いて下記コマンドを実行。

terminal
$ flutter pub run intl_translation:generate_from_arb \
    --output-dir=lib/l10n --no-use-deferred-loading \
    lib/l10n/l10n.dart lib/l10n/intl_*.arb

messages_all.dartが生成されます。

ここまでで基本的な前準備が完了です。


アプリを多言語化


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

MaterialApp(
  localizationsDelegates: [
    GlobalMaterialLocalizations.delegate, 
    GlobalWidgetsLocalizations.delegate,
    GlobalCupertinoLocalizations.delegate,
    const L10nDelegate(),
  ],
  supportedLocales: const [
    Locale('en'), // English
    Locale('ja'), // Japanese
  ],
  // ...
)

Global〜というdelegateは、Flutter公式のWidgetの多言語化用。

GlobalCupertinoLocalizationsは、CupertinoWidget使ってなければ不要だと思う。


各言語用のarbファイルを作成


生成されたintl_messages.arbをベースに、intl_en.arbintl_ja.arbを生成します。

lib/l10n/intl_en.arb
{
  "@@locale": "en",
  "title": "Hello World"
}
lib/l10n/intl_ja.arb
{
  "@@locale": "ja",
  "title": "こんにちは世界"
}

最終行末尾の , を入れるとエラーが出たので削除。

再度下記のコマンドを実行。

terminal
$ flutter pub run intl_translation:generate_from_arb \
    --output-dir=lib/l10n --no-use-deferred-loading \
    lib/l10n/l10n.dart lib/l10n/intl_*.arb

これで、下記ファイルが自動生成されます。

・messages_all.dart
・messages_en.dart
・messages_ja.dart
・messages_messages.dart


widgetでの呼び出し方法


以下のような形で呼び出せます。

Text(L10n.of(context).setting)


XcodeのLocalizations追加


iOSの言語設定をFlutterアプリに適用するにはXcodeでLocalizationsを追加する必要があります。

add-localization


用語を追加したい時


l10n.dartに新たに追記して

  String get setting {
    return Intl.message(
      'Setting',
      name: 'setting',
      desc: 'Setting',
      locale: localeName,
    );
  }

各言語ファイルにも追記します。

lib/l10n/intl_en.arb
{
  "@@locale": "en",
  "title": "Hello World",
  "setting": "Setting",}

lib/l10n/intl_ja.arb
{
  "@@locale": "ja",
  "title": "こんにちは世界",
  "setting": "設定",}

用語を追加したら、下記のようなスクリプトを用意しておいて実行します。

update_l10n.sh
#!/bin/sh
BLUE='\033[0;34m'
NC='\033[0m'

echo "${BLUE}==>1. Extract to arb${NC}"
flutter pub run intl_translation:extract_to_arb \
    --locale=messages \
    --output-dir=lib/l10n \
    lib/l10n/l10n.dart

echo "${BLUE}==>2. Generate dart file${NC}"
flutter pub run intl_translation:generate_from_arb \
    --output-dir=lib/l10n --no-use-deferred-loading \
    lib/l10n/l10n.dart lib/l10n/intl_*.arb

これで用語追加完了です。


Locale情報の取得


現在のLocaleはこんな感じで取得できる。

Locale myLocale = Localizations.localeOf(context);


参考URL


Internationalizing Flutter apps

Dart/Flutter での多言語対応あれこれ

If you like it, share it!