Flutterでアイコンをタップしたら音が出るシンプルなアプリを開発してリリースする 2/n 多言語対応
Flutterでアイコンをタップしたら音が出るシンプルなアプリを開発してリリースするまでをまとめるシリーズの2記事目です
概要
現在1歳1ヶ月の息子向けに、動物と乗り物のアイコンをタップすると音が鳴るシンプルなアプリを作っています。これをiOSとAndroid両方でリリースすることをゴールとしています。
前回まで
記事はこちらのタグに紐づけています。
https://zubora-code.net/ja/tags/first_flutter_tutorial
今回のゴール
前回で機能自体の実装は完了しました。今回の記事では、日本語と英語の両方に対応する方法を簡単に整理して書きます。完成系はこちらです。
実装
ライブラリのインストール
いくつか多言語対応用のライブラリがあるようですが、迷ったら公式ですね。flutter_localizations をインストールします。
https://docs.flutter.dev/accessibility-and-localization/internationalization
$ flutter pub add flutter_localizations --sdk=flutter
$ flutter pub add intl:any
MaterialAppのdelegateと対応localesを設定
import 'package:flutter/material.dart';
+import 'package:flutter_localizations/flutter_localizations.dart';
import 'Sound.dart';
void main() {
@@ -12,6 +13,15 @@ class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MaterialApp(
title: 'ぴよぴよサウンドパーク',
+ localizationsDelegates: const [
+ GlobalMaterialLocalizations.delegate,
+ GlobalWidgetsLocalizations.delegate,
+ GlobalCupertinoLocalizations.delegate,
+ ],
+ supportedLocales: const [
+ Locale('en'),
+ Locale('ja'),
+ ],
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.orange),
useMaterial3: true,
pubspec.yamlにgenerate flag: trueを追加
ライブラリインストール時に多言語対応のファイルが自動生成される設定を追加します。
flutter:
-
+ generate: true
l10n.yaml の追加
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
lib/l10n/app_en.arb, lib/l10n/app_ja.arb の追加
{
"appTitle": "PiyoPiyo Sound Park",
"@appTitle": {
"description": "The app title"
},
"animal": "Animal",
"@animal": {
"description": "Animal"
},
"vehicle": "Vehicle",
"@vehicle": {
"description": "Vehicle"
}
}
{
"appTitle": "ぴよぴよサウンドパーク",
"animal": "どうぶつ",
"vehicle": "のりもの"
}
app_en.arbをテンプレートファイルに指定しています。app_ja.arbは翻訳ファイルです。
flutter run コマンドを実行して .dart_tool/gen_l10n を自動生成
$ flutter run
main.dartからcontextに応じた値を取り出す
git diff lib/main.dart
diff --git a/lib/main.dart b/lib/main.dart
index 3b9397a..f3414a3 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
+import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'Sound.dart';
void main() {
@@ -12,29 +13,25 @@ class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "ぴよぴよサウンドパーク",
localizationsDelegates: const [
+ AppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
- supportedLocales: const [
- Locale('en'),
- Locale('ja'),
- ],
+ supportedLocales: AppLocalizations.supportedLocales,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.orange),
useMaterial3: true,
),
- home: const MyHomePage(title: 'ぴよぴよサウンドパーク'),
+ home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
- const MyHomePage({super.key, required this.title});
-
- final String title;
+ const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
@@ -141,23 +138,24 @@ class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
+ final l10n = AppLocalizations.of(context)!;
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
- title: Text(widget.title),
+ title: Text(l10n.appTitle),
),
body: Center(
child: _widgetOptions.elementAt(_selectedIndex),
),
bottomNavigationBar: BottomNavigationBar(
- items: const <BottomNavigationBarItem>[
+ items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
- icon: Icon(Icons.pets),
- label: 'どうぶつ',
+ icon: const Icon(Icons.pets),
+ label: l10n.animal,
),
BottomNavigationBarItem(
- icon: Icon(Icons.directions_car),
- label: 'のりもの',
+ icon: const Icon(Icons.directions_car),
+ label: l10n.vehicle,
),
],
currentIndex: _selectedIndex,
最後に
肌感覚としてはちょっと面倒でしたが、ルーティングとかがない分Web FrontEndよりは楽でした。せっかく世界に向けて公開できるのに日本語だけに閉じてしまうのはもったいないので、今後の開発でも多言語対応は積極的に行なっていきたいですね。
今回の修正は以下のPull Requestです。
https://github.com/tkugimot/touch_and_hear/pull/2?w=1
あと残りやりたいことは以下です。
- Crashlyticsの導入 (監視のため)
- AdMobの導入 (広告のため)
- アイコン/フィーチャーグラフィックの作成・設定
- サポートサイト/プライバシーポリシーサイトの作成
- Drawerの追加(アプリの使い方/お問い合わせ/プライバシーポリシーへのリンク)
- Androidへのリリース
- iOSへのリリース
次の記事ではCrashlyticsを導入しようと思います。