くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

Flutterで多言語対応する(l10n/flutter_localizations/intl)

Flutterで多言語対応する方法を少し調べてみたときの備忘録(*´ω`*)
(localization/l10nで、internationalization/i18nでじゃない)

公式ドキュメントはこのあたり

仕組みと流れ

基本的な流れはこんな感じ。

1..arbというjsonベースのリソースファイルを作成

// lib/l10n/app_en.arb
{
  "@@locale":"en",
  "helloWorld": "Hello World!"
}

// lib/l10n/app_ja.arb
{
  "@@locale":"ja",
  "helloWorld": "こんにちは世界"
}

2. fvm flutter gen-l10nを実行して、.dartに変換

  • app_localizations.dart ... エントリーポイントなファイル
  • app_localizations_en.dart ... 各言語のファイル(enの例)

3. app_localizations.dartを使う

// 多言語化の設定
const MaterialApp(
  title: 'Localizations Sample App',
  localizationsDelegates: AppLocalizations.localizationsDelegates,
  supportedLocales: AppLocalizations.supportedLocales,
);

// リソースファイルの利用
appBar: AppBar(
  title: Text(
    // デバイスの言語設定に応じて切り替わる
    AppLocalizations.of(context)!.helloWorld,
  ),
),

使い方

インストール

$ fvm flutter pub add flutter_localizations --sdk=flutter
$ fvm flutter pub add intl

pubspec.ymlはこんな感じ。

# pubspec.yml
dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  intl: ^0.18.0
flutter:
  # 言語ファイル生成のため、これも追加
  generate: true

設定ファイルの作成(l10n.yaml)

各種設定はl10n.yamlでおこなう。

# .arbファイルの配置ディレクトリ(デフォルト値)
arb-dir: lib/l10n
# ベースとなる.arbファイル(デフォルト値)
template-arb-file: app_en.arb
# 生成される.dartのファイル名(デフォルト値)
output-localization-file: app_localizations.dart

他のオプションはこちら。

リソースファイルの準備と生成

$ mkdir -p lib/l10n
$ touch lib/l10n/app_{en,ja}.arb

$ fvm flutter gen-l10n
# デフォルトではここに生成される
$ ls .dart_tool/flutter_gen/gen_l10n/
app_localizations.dart
app_localizations_en.dart
app_localizations_ja.dart

fvm flutter gen-l10nをしなくても、
fvm flutter runでも生成される。

生成ファイルの利用

# 生成されたdartファイルの読み込み
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

const MaterialApp(
  title: 'Localizations Sample App',
  // 生成されたクラスを利用
  localizationsDelegates: AppLocalizations.localizationsDelegates,
  supportedLocales: AppLocalizations.supportedLocales,
);

iOSでは追加の設定が必要

  1. ios/Runner.xcworkspaceを開く
  2. Project Navigatorで、Runner配下にあるInfo.plistを開く
  3. Information Property Listを選択
  4. EditorメニューのAdd Itemを選択
  5. ポップアップメニューのLocalizationsを選択
  6. 作成したLocalizationsを開く
  7. Valueフィールドに、supportedLocalesの言語を追加していく
  8. 全部の言語を追加したら保存する。

詳しくはこちら

小ネタ

アプリ全体の言語を指定する

class App extends HookConsumerWidget {
  const App({super.key});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    return MaterialApp.router(
      title: F.title,
      // l10nの設定
      localizationsDelegates: L10n.localizationsDelegates,
      supportedLocales: L10n.supportedLocales,
      // 利用言語を指定
      locale: const Locale("ja"),
    );
  }
}

特定のWidget配下で、Localeを上書きする

Widget build(BuildContext context) {
  return Scaffold(
    // Localizationsを使って、localeを上書き
    body: Localizations.override(
      context: context,
      // 上書きするコンテキストの指定
      locale: const Locale('es'),
      child: Builder(
        builder: (context) {
          // Builderを使って新しいcontextを扱えるようにする
          return // ...
        },
      ),
    ),
  );
}

現在の言語を取得する

Locale myLocale = Localizations.localeOf(context);

以上!! なんとなくわかってきたぞ。。