Flutter-国際化

現在、モバイルアプリケーションはさまざまな国の顧客によって使用されているため、アプリケーションはコンテンツをさまざまな言語で表示する必要があります。アプリケーションが複数の言語で機能できるようにすることを、アプリケーションの国際化と呼びます。

アプリケーションをさまざまな言語で動作させるには、最初にアプリケーションが実行されているシステムの現在のロケールを見つけてから、その特定のロケールでコンテンツを表示する必要があります。このプロセスはローカリゼーションと呼ばれます。

Flutterフレームワークは、ローカリゼーション用の3つの基本クラスと、アプリケーションをローカライズするための基本クラスから派生した広範なユーティリティクラスを提供します。

基本クラスは次のとおりです-

  • ロケール-ロケールは、ユーザーの言語を識別するために使用されるクラスです。たとえば、en-usはアメリカ英語を識別し、として作成できます。

Locale en_locale = Locale('en', 'US')

ここで、最初の引数は言語コードで、2番目の引数は国コードです。アルゼンチンスペイン語(es-ar)ロケールを作成する別の例は次のとおりです-

Locale es_locale = Locale('es', 'AR')
  • ローカリゼーション-ローカリゼーションは、ロケールとその子のローカライズされたリソースを設定するために使用される汎用ウィジェットです。

class CustomLocalizations { 
   CustomLocalizations(this.locale); 
   final Locale locale; 
   static CustomLocalizations of(BuildContext context) { 
      return Localizations.of<CustomLocalizations>(context, CustomLocalizations); 
   } 
   static Map<String, Map<String, String>> _resources = {
      'en': {
         'title': 'Demo', 
         'message': 'Hello World' 
      }, 
      'es': {
         'title': 'Manifestación', 
         'message': 'Hola Mundo', 
      }, 
   }; 
   String get title { 
      return _resources[locale.languageCode]['title']; 
   }
   String get message { 
      return _resources[locale.languageCode]['message']; 
   } 
}
  • ここで、CustomLocalizationsは、ウィジェットの特定のローカライズされたコンテンツ(タイトルとメッセージ)を取得するために特別に作成された新しいカスタムクラスです。ofメソッドはLocalizationsクラスを使用して、新しいCustomLocalizationsクラスを返します。

  • LocalizationsDelegate <T> − LocalizationsDelegate <T>は、Localizationsウィジェットがロードされるファクトリクラスです。これには3つのオーバーライド可能なメソッドがあります-

    • isSupported-ロケールを受け入れ、指定されたロケールがサポートされているかどうかを返します。

@override 
bool isSupported(Locale locale) => ['en', 'es'].contains(locale.languageCode);

      ここで、デリゲートはenおよびesロケールでのみ機能します。

    • load-ロケールを受け入れ、指定されたロケールのリソースのロードを開始します。

@override 
Future<CustomLocalizations> load(Locale locale) { 
   return SynchronousFuture<CustomLocalizations>(CustomLocalizations(locale)); 
}

      ここで、loadメソッドはCustomLocalizationsを返します。返されたCustomLocalizationsを使用して、英語とスペイン語の両方でタイトルとメッセージの値を取得できます。

    • shouldReload-ローカリゼーションウィジェットが再構築されるときにCustomLocalizationsのリロードが必要かどうかを指定します。

@override 
bool shouldReload(CustomLocalizationsDelegate old) => false;
  • CustomLocalizationDelegateの完全なコードは次のとおりです-

class CustomLocalizationsDelegate extends 
LocalizationsDelegate<CustomLocalizations> { 
   const CustomLocalizationsDelegate(); 
   @override 
   bool isSupported(Locale locale) => ['en', 'es'].contains(locale.languageCode);
   @override 
   Future<CustomLocalizations> load(Locale locale) { 
      return SynchronousFuture<CustomLocalizations>(CustomLocalizations(locale));
   } 
   @override bool shouldReload(CustomLocalizationsDelegate old) => false; 
}

一般に、Flutterアプリケーションは、MaterialAppまたはWidgetsAppの2つのルートレベルウィジェットに基づいています。Flutterは、両方のウィジェットに既製のローカリゼーションを提供します。これらは、MaterialLocalizationsとWidgetsLocaliationsです。さらに、FlutterはMaterialLocalizationsとWidgetsLocaliationsをロードするためのデリゲートも提供し、それぞれGlobalMaterialLocalizations.delegateとGlobalWidgetsLocalizations.delegateです。

概念をテストして理解するために、単純な国際化対応アプリケーションを作成しましょう。

  • 新しいフラッターアプリケーションflutter_localization_appを作成します。

  • Flutterは、専用のflutterパッケージflutter_localizationsを使用した国際化をサポートしています。アイデアは、ローカライズされたコンテンツをメインSDKから分離することです。pubspec.yamlを開き、以下のコードを追加して、国際化パッケージを有効にします-

dependencies: 
   flutter: 
      sdk: flutter 
   flutter_localizations:
      sdk: flutter
  • Android Studioは、pubspec.yamlが更新されたことを示す次のアラートを表示します。

  • [依存関係の取得]オプションをクリックします。Android Studioはインターネットからパッケージを取得し、アプリケーション用に適切に構成します。

  • 次のように、main.dartにflutter_localizationsパッケージをインポートします-

import 'package:flutter_localizations/flutter_localizations.dart'; 
import 'package:flutter/foundation.dart' show SynchronousFuture;
  • ここで、SynchronousFutureの目的は、カスタムローカリゼーションを同期的にロードすることです。

  • 以下に指定するように、カスタムローカリゼーションとそれに対応するデリゲートを作成します-

class CustomLocalizations { 
   CustomLocalizations(this.locale); 
   final Locale locale; 
   static CustomLocalizations of(BuildContext context) {
      return Localizations.of<CustomLocalizations>(context, CustomLocalizations); 
   }
   static Map<String, Map<String, String>> _resources = {
      'en': {
         'title': 'Demo', 
         'message': 'Hello World' 
      }, 
      'es': { 
         'title': 'Manifestación', 
         'message': 'Hola Mundo', 
      }, 
   }; 
   String get title { 
      return _resources[locale.languageCode]['title']; 
   } 
   String get message { 
      return _resources[locale.languageCode]['message']; 
   } 
}
class CustomLocalizationsDelegate extends
LocalizationsDelegate<CustomLocalizations> {
   const CustomLocalizationsDelegate();
   
   @override 
   bool isSupported(Locale locale) => ['en', 'es'].contains(locale.languageCode); 
   
   @override 
   Future<CustomLocalizations> load(Locale locale) { 
      return SynchronousFuture<CustomLocalizations>(CustomLocalizations(locale)); 
   } 
   @override bool shouldReload(CustomLocalizationsDelegate old) => false; 
}
  • ここで、CustomLocalizationsは、アプリケーションのタイトルとメッセージのローカリゼーションをサポートするために作成され、CustomLocalizationsDelegateはCustomLocalizationsをロードするために使用されます。

  • 以下に指定するように、MaterialAppプロパティ、localizationsDelegates、supportedLocalesを使用して、MaterialApp、WidgetsApp、CustomLocalizationのデリゲートを追加します-

localizationsDelegates: [
   const CustomLocalizationsDelegate(),   
   GlobalMaterialLocalizations.delegate, 
   GlobalWidgetsLocalizations.delegate, 
], 
supportedLocales: [
   const Locale('en', ''),
   const Locale('es', ''), 
],
  • CustomLocalizationsメソッドを使用して、タイトルとメッセージのローカライズされた値を取得し、以下に指定されている適切な場所で使用します-

class MyHomePage extends StatelessWidget {
   MyHomePage({Key key, this.title}) : super(key: key); 
   final String title; 
   @override 
   Widget build(BuildContext context) {
      return Scaffold(
         appBar: AppBar(title: Text(CustomLocalizations .of(context) .title), ), 
         body: Center(
            child: Column(
               mainAxisAlignment: MainAxisAlignment.center, 
               children: <Widget>[ 
                  Text( CustomLocalizations .of(context) .message, ), 
               ], 
            ), 
         ),
      );
   }
}
  • ここでは、簡単にするためにMyHomePageクラスをStatefulWidgetからStatelessWidgetに変更し、CustomLocalizationsを使用してタイトルとメッセージを取得しました。

  • アプリケーションをコンパイルして実行します。アプリケーションはその内容を英語で表示します。

  • アプリケーションを閉じます。に移動Settings → System → Languages and Input → Languages*

  • [言語の追加]オプションをクリックして、[スペイン語]を選択します。これにより、スペイン語がインストールされ、オプションの1つとしてリストされます。

  • スペイン語を選択し、英語の上に移動します。これは第一言語としてスペイン語として設定され、すべてがスペイン語のテキストに変更されます。

  • ここで国際化アプリケーションを再起動すると、タイトルとメッセージがスペイン語で表示されます。

  • 設定で英語オプションをスペイン語オプションの上に移動すると、言語を英語に戻すことができます。

  • アプリケーションの結果(スペイン語)は、以下のスクリーンショットに示されています-

intlパッケージの使用

Flutterは、ローカライズされたモバイルアプリケーションの開発をさらに簡素化するintlパッケージを提供します。intlパッケージは、言語固有のメッセージを半自動生成するための特別なメソッドとツールを提供します。

intlパッケージを使用して新しいローカライズされたアプリケーションを作成し、概念を理解しましょう。

  • 新しいフラッターアプリケーションflutter_intl_appを作成します。

  • pubspec.yamlを開き、パッケージの詳細を追加します。

dependencies: 
   flutter: 
      sdk: flutter 
   flutter_localizations: 
      sdk: flutter 
   intl: ^0.15.7 
   intl_translation: ^0.17.3
  • Android Studioは、pubspec.yamlが更新されたことを通知するアラートを以下に示すように表示します。

  • [依存関係の取得]オプションをクリックします。Android Studioはインターネットからパッケージを取得し、アプリケーション用に適切に構成します。

  • 前のサンプルflutter_internationalization_appからmain.dartをコピーします。

  • 以下に示すように、intlpacakgeをインポートします-

import 'package:intl/intl.dart';
  • 以下のコードに示すように、CustomLocalizationクラスを更新します-

class CustomLocalizations { 
   static Future<CustomLocalizations> load(Locale locale) {
      final String name = locale.countryCode.isEmpty ? locale.languageCode : locale.toString(); 
      final String localeName = Intl.canonicalizedLocale(name); 
      
      return initializeMessages(localeName).then((_) {
         Intl.defaultLocale = localeName; 
         return CustomLocalizations(); 
      }); 
   } 
   static CustomLocalizations of(BuildContext context) { 
      return Localizations.of<CustomLocalizations>(context, CustomLocalizations); 
   } 
   String get title {
      return Intl.message( 
         'Demo', 
         name: 'title', 
         desc: 'Title for the Demo application', 
      ); 
   }
   String get message{
      return Intl.message(
         'Hello World', 
         name: 'message', 
         desc: 'Message for the Demo application', 
      ); 
   }
}
class CustomLocalizationsDelegate extends 
LocalizationsDelegate<CustomLocalizations> {
   const CustomLocalizationsDelegate();
   
   @override
   bool isSupported(Locale locale) => ['en', 'es'].contains(locale.languageCode); 
   @override 
   Future<CustomLocalizations> load(Locale locale) { 
      return CustomLocalizations.load(locale); 
   } 
   @override 
   bool shouldReload(CustomLocalizationsDelegate old) => false; 
}
  • ここでは、カスタムメソッドの代わりに、intlパッケージの3つのメソッドを使用しました。それ以外の点では、概念は同じです。

    • Intl.canonicalizedLocale-正しいロケール名を取得するために使用されます。

    • Intl.defaultLocale-現在のロケールを設定するために使用されます

    • Intl.message-新しいメッセージを定義するために使用されます。

  • インポート l10n/messages_all.dartファイル。このファイルはまもなく生成されます

import 'l10n/messages_all.dart';
  • 次に、lib / l10nというフォルダーを作成します。

  • コマンドプロンプトを開き、アプリケーションのルートディレクトリ(pubspec.yamlが利用可能な場所)に移動して、次のコマンドを実行します-

flutter packages pub run intl_translation:extract_to_arb --output-
   dir=lib/l10n lib/main.dart
  • ここで、コマンドは、異なるロケールでメッセージを作成するためのテンプレートであるintl_message.arbファイルを生成します。ファイルの内容は次のとおりです-

{
   "@@last_modified": "2019-04-19T02:04:09.627551", 
   "title": "Demo", 
   "@title": {
      "description": "Title for the Demo application", 
      "type": "text", 
      "placeholders": {} 
   }, 
   "message": "Hello World", 
   "@message": {
      "description": "Message for the Demo 
      application", 
      "type": "text", 
      "placeholders": {} 
   }
}
  • intl_message.arbをコピーして、新しいファイルintl_en.arbを作成します。

  • intl_message.arbをコピーして、新しいファイルintl_es.arbを作成し、以下に示すようにコンテンツをスペイン語に変更します。

{
   "@@last_modified": "2019-04-19T02:04:09.627551",  
   "title": "Manifestación", 
   "@title": {
      "description": "Title for the Demo application", 
      "type": "text", 
      "placeholders": {} 
   },
   "message": "Hola Mundo",
   "@message": {
      "description": "Message for the Demo application", 
      "type": "text", 
      "placeholders": {} 
   } 
}
  • 次に、次のコマンドを実行して、最終的なメッセージファイルmessages_all.dartを作成します。

flutter packages pub run intl_translation:generate_from_arb 
--output-dir=lib\l10n --no-use-deferred-loading 
lib\main.dart lib\l10n\intl_en.arb lib\l10n\intl_es.arb
  • アプリケーションをコンパイルして実行します。上記のアプリケーションflutter_localization_appと同様に機能します。