Flutterで多言語化をしてみたので、その方法を書き留めておきます。
試してみたのは、タイトルやボトムナビゲーションバーの名称と、画面上に表示されるデータ(SQLiteに格納)を端末の言語設定にもとづいて言語切り替えすること。
本記事のソースコードはGitHubで公開していますので、必要であれば参照してください。
多言語化パッケージを追加する
flutter_localizationsを使うために、pubspec.yamlに多言語化パッケージを追加します。追加するパッケージは、
- flutter localizations
- intl package
の二つ。
dependencies:
flutter:
sdk: flutter
flutter_localizations: # for internationalization
sdk: flutter
intl: ^0.17.0
また、flutterの領域に、generate: trueを追加します。
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
generate: true # flutter localizations
追加したらpub getを実行します。
l10n.yaml
を新規作成する
l10n.yamlという名前がついたファイルをrootディレクトリに新規作成します。
l10n.yamlの内容は
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
記載されている意味は、
- 辞書化するファイルを${FLUTTER_PROJECT}/lib/l10n ディレクトリに配置する
- テンプレートファイルはapp_en.arb
- 翻訳した結果はapp_localizations.dartに記載される
という意味らしいです。
辞書ファイルを作成する
${FLUTTER_PROJECT}/lib/l10nに翻訳したい言語の数だけ辞書ファイルを作成します。
まずはテンプレートファイルであるapp_en.arbを新規作成し、lib/l10nディレクトリに配置します。
app_en.arb
{
"applicationTitle": "Flutter Localization Demo",
"@applicationTitle": {"description": "This is English version title."},
"home": "Home",
"@home": {},
"search": "Search",
"@search": {},
"bookmark": "Bookmark",
"@bookmark": {}
}
つぎに日本語のためにapp_ja.arbを新規作成し、lib/l10nディレクトリに配置します。
app_ja.arb
{
"applicationTitle": "Flutter多言語デモ",
"@applicationTitle": {"description": "これは日本語版のアプリ名です。"},
"home": "ホーム",
"@home": {},
"search": "検索",
"@search": {},
"bookmark": "ブックマーク",
"@bookmark": {}
}
main.dartを書く
次の二つのライブラリをimportします
main.dart
import 'package:flutter_localizations/flutter_localizations.dart';
MaterialAppに次のコードを追加します
return MaterialApp(
title: 'Localizations Sample App',
localizationsDelegates: const [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: const [
Locale('en', ''), // English, no country code
Locale('ja', ''), // Japanese, no country code
],
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
ここでアプリを一度実行します。実行すると下記ディレクトリにファイルが生成されます。
${FLUTTER_PROJECT}/.dart_tool/flutter_gen/gen_l10n
.
ファイル生成を確認できたらさらにコードを追加します。
main.dart
app_localization.dartをimportします。
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
MaterialAppに下記1行を追加します。
return const MaterialApp(
title: 'Localizations Sample App',
localizationsDelegates: [
AppLocalizations.delegate, // Add this line
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
//以下省略
AppBar
appBar: AppBar(
title: Text(AppLocalizations.of(context)!.applicationTitle),
),
AppLocalizations.of(context)!.applicationTitle では、app_en.arbに定義されたapplicationTitleの文字列が言語設定に基づいて返されます。
今回のサンプルでは、
- “en”ならFlutter Localization Demo
- “ja”ならFlutter多言語デモ
のいずれかが表示されます。
後は翻訳したいところに上記を適用していけばよいので、
bottomNavigationBar
bottomNavigationBar: BottomNavigationBar(
items: [
BottomNavigationBarItem(
icon: const Icon(Icons.home),
label: AppLocalizations.of(context)!.home),
BottomNavigationBarItem(
icon: const Icon(Icons.search),
label: AppLocalizations.of(context)!.search),
BottomNavigationBarItem(
icon: const Icon(Icons.bookmark),
label: AppLocalizations.of(context)!.bookmark),
],
),
のように書けます。
SQLiteからデータを取得する
SQLiteのデータ作成や取得のふるまいはsqlite_helper.dartに定義しました。
テーブルの設計はこんな感じです(この設計はベストではないかも…です)
データ作成・取得のふるまい(SQLiteの取り扱い)はサンプルソースコードを参照してください。
SQLiteのデータ取得のメソッドをmain.dartから呼び出します。その際に、現在の端末の言語設定を取得してから、当該言語のデータを取りに行くように書きました。
言語設定を取得するには
//get a current language setting
Locale locale = Localizations.localeOf(context);
String languageCode = locale.languageCode;
debugPrint(languageCode);
でできます。
あとは、変数languageCodeに格納された”en”や”ja”をデータベースヘルパーに渡してあげれば、言語ごとのデータを取得できます。
例えばデータ取得は
sqlite_helper.dart
//get data from sqlite table
Future<List<Map>> dataSelect(String locale) async {
String sqlQuery;
var databasesPath = await getDatabasesPath();
String path = join(databasesPath, 'demo.db'); //import path/path.dart
Database database = await openDatabase(path);
// Get the records
if (locale == "en") {
sqlQuery = 'SELECT * FROM vehicle_master';
} else {
sqlQuery = 'SELECT * FROM vehicle_other where language = "$locale"';
}
List<Map> list = await database.rawQuery(sqlQuery);
await database.close();
return list;
}
引数でlocaleを渡します。
ちなみにデータを取得する処理はすべて非同期のため、main.dartではFutureBuilderを使います。
実行
アプリを実行すると下記のディレクトリに辞書ファイルが生成されます。
${FLUTTER_PROJECT}/.dart_tool/flutter_gen/gen_l10n
以上、Flutter多言語化のサンプルでした。
おわり。