目次
はじめに
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.dartlib/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