目次
はじめに
Flutter で国際化対応するときに便利な Google app script を用いたファイル生成を紹介します。
intl_translation パッケージが,null safety をサポートしなくなりました。
今後は,flutter generate でファイルを生成する必要がありますが,arb を手書きしてくのは辛いので Google スプレッドシートで翻訳情報を管理すると楽になるので管理方法を紹介します。
国際化(i18n)対応をする
pubspec.yaml
の dependecies に flutter_localizations と intl を追加します。同様に flutter の generate フラグを true にします。
dependencies:
flutter:
sdk: flutter
flutter_localizations:
sdk: flutter
intl: ^0.17.0
flutter:
generate: true
ルートディレクトリに l10n.yaml というファイルを作ります。ここに generate 先や参照元を指定できます。
arb-dir: lib/l10n
template-arb-file: intl_ja.arb
output-localization-file: app_localizations.dart
lib/l10n 以下に*.arb ファイルを配置します。
intl_ja.arb
{ "@@locale": "ja", "helloworld": "ハローワールド" }
intl_en.arb
{ "@@locale": "en", "helloworld": "helloworld" }
iOS の場合は,open ios/Runner.xcworkspace
で workspace を開きます。
Localizations に対応したい言語を追加します。
アプリケーション側の対応
生成されたファイルを import します。
import 'package:fluttergen/genl10n/app_localizations.dart';
国際化対応したい文字列はAppLocalizations.of(context)!.helloWorld
で呼び出す事ができます。
最小構成のサンプルコードは以下のようになります。
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Localizations Sample App',
localizationsDelegates: [
AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
supportedLocales: [
Locale('en', ''),
Locale('ja', ''),
],
home: MyHomePage(),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
AppLocalizations.of(context)!.helloworld,
),
],
),
),
);
}
}
GoogleAppScript を用いて国際化対応に必要なファイルを生成する
スプレッドシートを作成します。
今回用意したスクリプトでは,4 行目から翻訳対象のデータとしています。
また,#をつけることでコメントを書くことが出来るようにしています。ユースケースやスクリーンに対応したコメントを付与できます。
A 列目に メソッド名、B 列目に翻訳文字列に対する説明、C 列目以降に文字列を入れるようにしています。
ツールからスクリプトエディタを選択し,myFunction を実行することで GoogleDrive に*.arb が生成されます。
ファイルをダウンロードし,lib/l10n 以下に配置することで使用することが出来ます。
const col_key = 0;
const col_desc = 1;
const col_ja = 2;
const col_en = 3;
const row_data_start = 3;
const comment_out_string = "#";
function generateArb(data) {
const exportHeader = "{\n";
const exportFooter = "}\n";
const arbSettings = [
{
locale: "ja",
file_name: "intl_ja.arb",
col: col_ja,
},
{
locale: "en",
file_name: "intl_en.arb",
col: col_en,
},
];
arbSettings.forEach(arb => {
let exportData = "";
exportData += exportHeader;
let locale = ` "@@locale": "${arb["locale"]}",\n`;
exportData += locale;
data.forEach(function (e, index, array) {
if (index === array.length - 1) {
exportData += ` "${e[col_key]}": "${e[arb["col"]]}"\n`;
} else {
exportData += ` "${e[col_key]}": "${e[arb["col"]]}",\n`;
}
});
exportData += exportFooter;
exportDataToDrive(exportData, arb["file_name"]);
});
}
function exportDataToDrive(data, fileName) {
const blob = Utilities.newBlob(data, MimeType.PLAIN_TEXT, fileName);
DriveApp.createFile(blob);
}
function myFunction() {
const sheet = SpreadsheetApp.getActiveSheet();
const data = sheet.getDataRange().getValues();
const transData = data.splice(row_data_start, data.length);
const filtterdTransData = transData
.filter(e => e[col_key] !== "")
.filter(e => e[col_key].slice(0, 1) !== comment_out_string);
generateArb(filtterdTransData);
}
サンプルプロジェクトを用意しました。実際に試してみたい方はぜひ使ってください 🎅🏽 https://github.com/kawa1214/flutter-l10n-app-script