Flutter - Quốc tế hóa

Ngày nay, các ứng dụng di động được sử dụng bởi khách hàng từ các quốc gia khác nhau và do đó, các ứng dụng được yêu cầu hiển thị nội dung bằng các ngôn ngữ khác nhau. Việc cho phép một ứng dụng hoạt động bằng nhiều ngôn ngữ được gọi là Quốc tế hóa ứng dụng.

Để một ứng dụng hoạt động ở các ngôn ngữ khác nhau, trước tiên nó phải tìm ngôn ngữ hiện tại của hệ thống mà ứng dụng đang chạy và sau đó cần hiển thị nội dung của ứng dụng bằng ngôn ngữ cụ thể đó và quá trình này được gọi là Bản địa hóa.

Khung công tác Flutter cung cấp ba lớp cơ sở để bản địa hóa và các lớp tiện ích mở rộng bắt nguồn từ các lớp cơ sở để bản địa hóa một ứng dụng.

Các lớp cơ sở như sau:

  • Locale - Locale là một lớp được sử dụng để xác định ngôn ngữ của người dùng. Ví dụ: en-us xác định tiếng Anh Mỹ và nó có thể được tạo như.

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

Ở đây, đối số đầu tiên là mã ngôn ngữ và đối số thứ hai là mã quốc gia. Một ví dụ khác về việc tạo ngôn ngữ tiếng Tây Ban Nha (es-ar) Argentina như sau:

Locale es_locale = Locale('es', 'AR')
  • Bản địa hoá - Bản địa hoá là một tiện ích con chung được sử dụng để đặt Ngôn ngữ và các tài nguyên được bản địa hoá của con của nó.

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']; 
   } 
}
  • Ở đây, CustomLocalizations là một lớp tùy chỉnh mới được tạo đặc biệt để lấy nội dung bản địa hóa nhất định (tiêu đề và thông điệp) cho tiện ích con. of method sử dụng lớp Localizations để trả về lớp CustomLocalizations mới.

  • LocalizationsDelegate <T> - LocalizationsDelegate <T> là một lớp nhà máy mà qua đó tiện ích Localizations được tải. Nó có ba phương pháp có thể loại bỏ -

    • isSupported - Chấp nhận một ngôn ngữ và trả về liệu ngôn ngữ được chỉ định có được hỗ trợ hay không.

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

      Ở đây, ủy quyền chỉ hoạt động cho ngôn ngữ en và es.

    • tải - Chấp nhận một ngôn ngữ và bắt đầu tải các tài nguyên cho ngôn ngữ được chỉ định.

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

      Tại đây, phương thức tải trả về CustomLocalizations. Các CustomLocalizations trả về có thể được sử dụng để lấy các giá trị của tiêu đề và thông điệp bằng cả tiếng Anh và tiếng Tây Ban Nha

    • shouldReload - Chỉ định xem có cần tải lại CustomLocalizations hay không khi tiện ích con Localizations của nó được xây dựng lại.

@override 
bool shouldReload(CustomLocalizationsDelegate old) => false;
  • Mã hoàn chỉnh của CustomLocalizationDelegate như sau:

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; 
}

Nói chung, các ứng dụng Flutter dựa trên hai widget cấp cơ sở là MaterialApp hoặc WidgetsApp. Flutter cung cấp bản địa hóa sẵn sàng cho cả hai widget và chúng là MaterialLocalizations và WidgetsLocaliations. Hơn nữa, Flutter cũng cung cấp các đại biểu để tải MaterialLocalizations và WidgetsLocaliations và chúng lần lượt là GlobalMaterialLocalizations.delegate và GlobalWidgetsLocalizations.delegate.

Hãy để chúng tôi tạo một ứng dụng hỗ trợ quốc tế hóa đơn giản để kiểm tra và hiểu khái niệm này.

  • Tạo một ứng dụng flashing mới, flay_localization_app.

  • Flutter hỗ trợ quốc tế hóa bằng cách sử dụng gói Flutter độc quyền, Flutter_localizations. Ý tưởng là tách nội dung bản địa hóa khỏi SDK chính. Mở pubspec.yaml và thêm mã bên dưới để kích hoạt gói quốc tế hóa -

dependencies: 
   flutter: 
      sdk: flutter 
   flutter_localizations:
      sdk: flutter
  • Android studio sẽ hiển thị cảnh báo sau rằng pubspec.yaml đã được cập nhật.

  • Nhấp vào Nhận tùy chọn phụ thuộc. Android studio sẽ lấy gói từ Internet và định cấu hình đúng cách cho ứng dụng.

  • Nhập gói flay_localizations trong main.dart như sau:

import 'package:flutter_localizations/flutter_localizations.dart'; 
import 'package:flutter/foundation.dart' show SynchronousFuture;
  • Ở đây, mục đích của SynchronousFuture là tải các bản địa hóa tùy chỉnh một cách đồng bộ.

  • Tạo bản địa hóa tùy chỉnh và đại biểu tương ứng của nó như được chỉ định bên dưới -

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; 
}
  • Ở đây, CustomLocalizations được tạo để hỗ trợ bản địa hóa cho tiêu đề và thông điệp trong ứng dụng và CustomLocalizationsDelegate được sử dụng để tải CustomLocalizations.

  • Thêm đại diện cho MaterialApp, WidgetsApp và CustomLocalization bằng cách sử dụng các thuộc tính MaterialApp, localizationsDelegates và hỗ trợLocales như được chỉ định bên dưới -

localizationsDelegates: [
   const CustomLocalizationsDelegate(),   
   GlobalMaterialLocalizations.delegate, 
   GlobalWidgetsLocalizations.delegate, 
], 
supportedLocales: [
   const Locale('en', ''),
   const Locale('es', ''), 
],
  • Sử dụng phương pháp CustomLocalizations để nhận giá trị bản địa hóa của tiêu đề và thông báo và sử dụng nó ở vị trí thích hợp như được chỉ định bên dưới -

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, ), 
               ], 
            ), 
         ),
      );
   }
}
  • Ở đây, chúng tôi đã sửa đổi lớp MyHomePage từ StatefulWidget thành StatelessWidget vì lý do đơn giản và sử dụng CustomLocalizations để lấy tiêu đề và tin nhắn.

  • Biên dịch và chạy ứng dụng. Ứng dụng sẽ hiển thị nội dung của nó bằng tiếng Anh.

  • Đóng ứng dụng. Đi đếnSettings → System → Languages and Input → Languages*.

  • Nhấp vào Thêm tùy chọn ngôn ngữ và chọn tiếng Tây Ban Nha. Thao tác này sẽ cài đặt ngôn ngữ Tây Ban Nha và sau đó liệt kê nó là một trong các tùy chọn.

  • Chọn tiếng Tây Ban Nha và chuyển nó lên trên tiếng Anh. Điều này sẽ đặt là tiếng Tây Ban Nha làm ngôn ngữ đầu tiên và mọi thứ sẽ được thay đổi thành văn bản tiếng Tây Ban Nha.

  • Bây giờ khởi chạy lại ứng dụng quốc tế hóa và bạn sẽ thấy tiêu đề và tin nhắn bằng tiếng Tây Ban Nha.

  • Chúng tôi có thể hoàn nguyên ngôn ngữ sang tiếng Anh bằng cách di chuyển tùy chọn tiếng Anh lên trên tùy chọn tiếng Tây Ban Nha trong cài đặt.

  • Kết quả của ứng dụng (bằng tiếng Tây Ban Nha) được hiển thị trong ảnh chụp màn hình dưới đây -

Sử dụng gói intl

Flutter cung cấp gói intl để đơn giản hóa hơn nữa việc phát triển ứng dụng di động được bản địa hóa. Gói intl cung cấp các phương pháp và công cụ đặc biệt để tạo bán tự động các thông báo ngôn ngữ cụ thể.

Hãy để chúng tôi tạo một ứng dụng bản địa hóa mới bằng cách sử dụng gói intl và hiểu khái niệm này.

  • Tạo một ứng dụng rung mới, flut_intl_app.

  • Mở pubspec.yaml và thêm chi tiết gói.

dependencies: 
   flutter: 
      sdk: flutter 
   flutter_localizations: 
      sdk: flutter 
   intl: ^0.15.7 
   intl_translation: ^0.17.3
  • Android studio sẽ hiển thị cảnh báo như hình dưới đây thông báo rằng pubspec.yaml đã được cập nhật.

  • Nhấp vào Nhận tùy chọn phụ thuộc. Android studio sẽ lấy gói từ Internet và định cấu hình đúng cách cho ứng dụng.

  • Sao chép main.dart từ mẫu trước đó, flay_internationalization_app.

  • Nhập pacakge intl như hình dưới đây -

import 'package:intl/intl.dart';
  • Cập nhật lớp CustomLocalization như được hiển thị trong đoạn mã dưới đây -

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; 
}
  • Ở đây, chúng tôi đã sử dụng ba phương thức từ gói intl thay vì các phương thức tùy chỉnh. Nếu không, các khái niệm đều giống nhau.

    • Intl.canonicalizedLocale - Được sử dụng để lấy tên miền địa phương chính xác.

    • Intl.defaultLocale - Được sử dụng để đặt ngôn ngữ hiện tại

    • Intl.message - Được sử dụng để xác định các tin nhắn mới.

  • nhập khẩu l10n/messages_all.darttập tin. Chúng tôi sẽ sớm tạo tệp này

import 'l10n/messages_all.dart';
  • Bây giờ, hãy tạo một thư mục, lib / l10n

  • Mở dấu nhắc lệnh và đi đến thư mục gốc của ứng dụng (nơi có sẵn pubspec.yaml) và chạy lệnh sau:

flutter packages pub run intl_translation:extract_to_arb --output-
   dir=lib/l10n lib/main.dart
  • Tại đây, lệnh sẽ tạo tệp intl_message.arb, một mẫu để tạo thông báo bằng ngôn ngữ khác nhau. Nội dung của tập tin như sau:

{
   "@@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": {} 
   }
}
  • Sao chép intl_message.arb và tạo tệp mới, intl_en.arb.

  • Sao chép intl_message.arb và tạo tệp mới, intl_es.arb và thay đổi nội dung sang ngôn ngữ Tây Ban Nha như hình dưới đây -

{
   "@@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": {} 
   } 
}
  • Bây giờ, hãy chạy lệnh sau để tạo tệp tin nhắn cuối cùng, 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
  • Biên dịch và chạy ứng dụng. Nó sẽ hoạt động tương tự như ứng dụng ở trên, flay_localization_app.