【Flutter】easy_localizationを使ったシンプルな言語変換アプリの作成方法

image

今回はFlutter製アプリでの言語変換の方法をご紹介します。
ボタン一つで言語が変換できるようになります。
この記事では、以下のような日本語と英語の変換を行うアプリの作り方を説明していきます。

言語変換アプリ

環境

  • Flutter version 2.2.2
  • Dart version 2.13.3
  • easy_localization: ^3.0.0

使用パッケージ(easy_localization)

使用するパッケージはeasy_localizationです。
アプリの多言語化を行う場合には、このパッケージを使用することが多いと思います。
以下でパッケージインストールから、ソースコード以外の設定部分の説明をしていきます。

easy_localizationのインストール

pubspec.yamldependenciesに以下を追加

dependencies:
  easy_localization: ^3.0.0 #最新のものを使用してください

そしてflutter pub getでOKです。 詳細は公式のインストールページを参照してください。

言語のjsonファイルの準備

使用するテキストはjsonファイルで管理します。

1.プロジェクトのディレクトリにassets/langsフォルダを追加

テキストを管理するためのフォルダを用意します。

2.langsフォルダ内にテキストを管理するjsonファイルを用意

日本語のテキストを管理するja-JP.jsonと英語を管理するen-US.jsonを用意します。
jsonファイルを追加後の構造は以下のようになります。

assets
└── langs
    ├── en-US.json
    └── ja-JP.json

3.pubspec.yamlファイルassetの場所を宣言する

pubspec.yamlファイルのassetsの部分に、上記で追加したフォルダ(langs)のパスを追加します。

assets:
    - assets/langs/

easy_localizationを用いたFlutter製の言語変換アプリの作成手順

以下ではFlutter製言語変換アプリのソースコード部分を説明していきます。

コード全文

とりあえずソースコード全文を記載します。 詳細やポイントに関しては、以下で説明していきます。

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:easy_localization/easy_localization.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await EasyLocalization.ensureInitialized();

  runApp(EasyLocalization(
    child: MyApp(),
    supportedLocales: [Locale('ja', 'JP'), Locale('en', 'US')],
    path: 'assets/langs',
    fallbackLocale: Locale('ja', 'JP'),
    saveLocale: false,
  ));
}

class MyApp extends StatelessWidget {
  
  Widget build(BuildContext context) {
    final _ezContext = EasyLocalization.of(context)!;
    return MaterialApp(
      title: 'Change Lang App',
      debugShowCheckedModeBanner: false,
      localizationsDelegates: [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        _ezContext.delegate,
      ],
      supportedLocales: _ezContext.supportedLocales,
      locale: _ezContext.locale,
      theme: ThemeData(primarySwatch: Colors.blue),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage();

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text(tr('title'), style: TextStyle(fontSize: 20))),
      body: _body(context),
    );
  }

  Widget _body(BuildContext context) {
    final supportLocales = context.supportedLocales;
    final currentLocale = context.locale;
    return Center(
      child: Column(
        children: [
          Row(
              mainAxisSize: MainAxisSize.min,
              children: supportLocales
                  .map((locale) => _btn(context, locale, currentLocale))
                  .toList()),
          const SizedBox(height: 20),
          Text(tr('lang_name'), style: TextStyle(fontSize: 16)),
          const SizedBox(height: 4),
          //context.localeで現在のlocaleが取得できる
          Text(context.locale.toString(), style: TextStyle(fontSize: 16))
        ],
      ),
    );
  }

  Widget _btn(BuildContext context, Locale locale, Locale currentLocale) {
    final isActive = locale.languageCode == currentLocale.languageCode;
    return Padding(
      padding: const EdgeInsets.all(8),
      child: ElevatedButton(
          style: ElevatedButton.styleFrom(
              primary: isActive
                  ? Theme.of(context).accentColor
                  : Theme.of(context).disabledColor),
          onPressed: () => context.setLocale(locale),
          child: Text(locale.languageCode)),
    );
  }
}

コードの詳細部分に関して、説明を加えていきます。

初期化処理

main関数の中は以下の通りです。
runAppの前でEasyLocalization.ensureInitialized()を呼び出します。

void main() async {
 //公式ドキュメントより↓   
 // Needs to be called so that we can await for EasyLocalization.ensureInitialized();
  WidgetsFlutterBinding.ensureInitialized();
  await EasyLocalization.ensureInitialized();

  runApp(...);
}

言語に関する詳細設定

以下で言語に関する詳細設定を行っています。

  • サポート言語(supportedLocales)
  • 言語ファイル(jsonファイル)のパス
  • 言語が取得できなかった場合のデフォルト言語
  • 端末ストレージに言語情報を保存するかどうか
  runApp(EasyLocalization(
    child: MyApp(),
    supportedLocales: [Locale('ja', 'JP'), Locale('en', 'US')],
    path: 'assets/langs',
    fallbackLocale: Locale('ja', 'JP'),
    saveLocale: false,
  ));

他にも詳細設定できるので、必要であればカスタマイズしてみてください。

MaterialApp内の言語設定

final _ezContext = EasyLocalization.of(context)!;
_ezContextに上記で設定した言語情報が入っています。

Widget build(BuildContext context) {
    final _ezContext = EasyLocalization.of(context)!;
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      localizationsDelegates: [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        _ezContext.delegate,
      ],
      supportedLocales: _ezContext.supportedLocales,
      locale: _ezContext.locale,
      theme: ThemeData(primarySwatch: Colors.blue),
      home: MyHomePage(),
    );
  }

言語情報の取得

MyHomePageクラス内で、以下のように言語情報が取得できます。

final supportLocales = context.supportedLocales; //サポート言語リスト
final currentLocale = context.locale; //現在の言語

言語変換方法

context.setLocale(locale)で言語が変換できます。
localeの中に適用したい言語を入れます。

このアプリでは、ボタンで言語情報が変更できるようになっているので、ボタンのonPressedcontext.setLocale(locale)を呼んでいます。

    ElevatedButton(
          style: ElevatedButton.styleFrom(
              primary: isActive
                  ? Theme.of(context).accentColor
                  : Theme.of(context).disabledColor),
          onPressed: () => context.setLocale(locale), //ここ
          child: Text(locale.languageCode))

言語ごとのjsonファイルの中身

AppBarのタイトルと言語名の2つのみ用意してあります。
ja-JP.json

{
  "lang_name": "日本語",
  "title": "言語変換アプリ"
}

en-US.json

{
  "lang_name": "English",
  "title": "Change Lang App"
}

これで簡単なFlutter製の言語変換アプリの完成です。

まとめ

いかがでしたでしょうか。 上で説明したように、意外とシンプルに言語をスイッチングできます。 言語変換機能の組み込みの際に参考にしていただけると幸いです。

Githubのリポジトリこちら

参考

easy_localizationの基本的な使用方法は公式ページを参考にしています。