• 多语言(国际化)


    国际化(internationalization 简称 i18n
      终端(手机)系统语言切换时,flutter 应用跟随切换
     
    内容
      组件(Widget)国际化
        例如:日历、弹窗等常用组件的国际化

      文本国际化(包括文本的顺序)
        自定义文本的国际化

    1、组件国际化
     
    使用步骤:
    (1)、在 pubspec.yaml 中引入 flutter_localizations
     
    (2)、设置 MaterialApp
        ①、import 'package:flutter_localizations/flutter_localizations.dart';
        ②、 localizationsDelegates(指定哪些组件需要进行国际化)
        ③、supportedLocales(指定要支持哪些语言)
     
    例如:在 main.dart 中添加以上设置内容
    import 'package:flutter/material.dart';
    import 'package:flutter_localizations/flutter_localizations.dart';
    import '09_form/form_05_datepicker.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return const MaterialApp(
          title: "Flutter Demo",
          home: Home(),
          debugShowCheckedModeBanner: false,
          // 国际化
          localizationsDelegates: [
            // 本地化代理
            GlobalMaterialLocalizations.delegate, // Material 国际化
            GlobalCupertinoLocalizations.delegate, // Cupertino 国际化
            GlobalWidgetsLocalizations.delegate, // 组件国际化
          ],
          supportedLocales: [
            Locale('en', 'US'), // 美国英语
            Locale('zh', 'CN'), // 简体中文
          ],
        );
      }
    }
    (3)、查看组件效果
      在模拟器上,切换语言,然后,查看组件效果(例如:日历)

    2、文本国际化

    使用步骤:

    (1)、创建本地化类 CustomLocalizations
    (2)、创建本地化类的代理
          CustomLocalizationsDelegate extends LocalizationsDelegate<CustomLocalizations>
            isSupported(当前本地化,是否在有效的语言范围内)
            shouldReload(本地化重新构建时,是否调用 load 方法,加载本地化资源)
            load(语言发生变更时,加载对应的本地化资源)
    // CustomLocalizations.dart
    
    import 'package:flutter/foundation.dart';
    import 'package:flutter/material.dart';
    
    class CustomLocalizations {
      final Locale locale;
      CustomLocalizations(this.locale);
    
      static final Map<String, Map<String, String>> _localizedValues = {
        'en': {
          'title': 'Home',
          'greet': 'Hello',
        },
        'zh': {
          'title': '首页',
          'greet': '你好',
        }
      };
    
      String? t(String key) {
        return _localizedValues[locale.languageCode]![key];
      }
    
      static CustomLocalizations of(BuildContext context) {
        return Localizations.of(context, CustomLocalizations);
      }
    
      static CustomLocalizationsDelegate delegate = CustomLocalizationsDelegate();
    }
    
    class CustomLocalizationsDelegate
        extends LocalizationsDelegate<CustomLocalizations> {
      // 当前本地化,是否在有效的语言范围内
      @override
      bool isSupported(Locale locale) {
        return ['en', 'zh'].contains(locale.languageCode);
      }
    
      // 语言发生变更时,加载对应的本地化资源
      @override
      Future<CustomLocalizations> load(Locale locale) {
        return SynchronousFuture(CustomLocalizations(locale));
      }
    
      // 本地化重新构建时,是否调用 load 方法,加载本地化资源
      @override
      bool shouldReload(covariant LocalizationsDelegate<CustomLocalizations> old) {
        return false;
      }
    }
    (3)、使用本地化类 CustomLocalizations.delegate
    // main.dart
    
    import 'package:flutter/material.dart';
    import 'package:flutter_localizations/flutter_localizations.dart';
    import '11_theme/theme_01_i18n.dart';
    import '11_theme/CustomLocalizations.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: "Flutter Demo",
          home: const Home(),
          debugShowCheckedModeBanner: false,
          // 国际化
          localizationsDelegates: [
            // 本地化代理
            CustomLocalizations.delegate,
            GlobalMaterialLocalizations.delegate, // Material 国际化
            GlobalCupertinoLocalizations.delegate, // Cupertino 国际化
            GlobalWidgetsLocalizations.delegate, // 组件国际化
          ],
          supportedLocales: const [
            Locale('en', 'US'), // 美国英语
            Locale('zh', 'CN'), // 简体中文
          ],
        );
      }
    }

    (4)、新建一个 theme_01_i18n.dart 文件,使用文本国际化,查看效果

    import 'package:flutter/material.dart';
    import 'CustomLocalizations.dart';
    
    class Home extends StatelessWidget {
      const Home({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            // 文本国际化
            title: Text(
              Localizations.of(context, CustomLocalizations).t('title'),
            ),
          ),
          body: const HomePage(),
        );
      }
    }
    
    class HomePage extends StatelessWidget {
      const HomePage({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Center(
          // 文本国际化
          child: Text(
            Localizations.of(context, CustomLocalizations).t('greet'),
            style: const TextStyle(fontSize: 60),
          ),
        );
      }
    }

    3、加载语言包

    使用步骤:
    (1)、检测当前语言
      loadResolutionCallback
        locale.languageCode (语言代码,例如:en、zh)
        locale.countryCode (国家代码,例如:US、CN)
    // main.dart
    
    import 'package:flutter/material.dart';
    import 'package:flutter_localizations/flutter_localizations.dart';
    import '11_theme/theme_01_i18n.dart';
    import '11_theme/CustomLocalizations.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: "Flutter Demo",
          home: const Home(),
          debugShowCheckedModeBanner: false,
          // 国际化
          localizationsDelegates: [
            // 本地化代理
            CustomLocalizations.delegate,
            GlobalMaterialLocalizations.delegate, // Material 国际化
            GlobalCupertinoLocalizations.delegate, // Cupertino 国际化
            GlobalWidgetsLocalizations.delegate, // 组件国际化
          ],
          supportedLocales: const [
            Locale('en', 'US'), // 美国英语
            Locale('zh', 'CN'), // 简体中文
          ],
          // 检测当前语言
          localeResolutionCallback: (locale, supportedLocales) {
            print('device locale: $locale'); // device locale: zh_Hans_CN
            print('supportedLocales: $supportedLocales'); // [en_US, zh_CN]
            for (var supportedLocale in supportedLocales) {
              print('supportedLocale: $supportedLocale');
              // supportedLocale: en_US
              // supportedLocale: zh_CN
              if (supportedLocale.languageCode == locale?.languageCode &&
                  supportedLocale.countryCode == locale?.countryCode) {
                return supportedLocale;
              }
            }
            return supportedLocales.first;
          },
        );
      }
    }
    (2)、设置语言包
      ①、创建语言文件
      ②、在 pubspec.yaml 中配置语言资源
    (3)、异步加载语言包
      ①、在 CustomLocalizations 中,添加 loadJson() 方法
      ②、在 CustomLocalizationsDelegate 中,调用 CustomLocalizations 的 loadJson() 方法
    // CustomLocalizations.dart
    
    import 'dart:convert';
    
    // import 'package:flutter/foundation.dart';
    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    
    class CustomLocalizations {
      final Locale locale;
      CustomLocalizations(this.locale);
    
      // static final Map<String, Map<String, String>> _localizedValues = {
      //   'en': {
      //     'title': 'Home',
      //     'greet': 'Hello',
      //   },
      //   'zh': {
      //     'title': '首页',
      //     'greet': '你好',
      //   }
      // };
    
      // String? t(String key) {
      //   return _localizedValues[locale.languageCode]![key];
      // }
    
      // 加载本地语言包
      late Map<String, String> _localizedValues;
    
      Future<bool> loadJson() async {
        String jsonString =
            await rootBundle.loadString('lang/${locale.languageCode}.json');
        Map<String, dynamic> jsonMap = jsonDecode(jsonString);
        _localizedValues =
            jsonMap.map((key, value) => MapEntry(key, value.toString()));
        print('_localizedValues, $_localizedValues');
        // _localizedValues, {title: 主页, greet: 你好 Flutter}
        return true;
      }
    
      String? t(String key) {
        return _localizedValues[key];
      }
    
      static CustomLocalizations of(BuildContext context) {
        return Localizations.of(context, CustomLocalizations);
      }
    
      static CustomLocalizationsDelegate delegate = CustomLocalizationsDelegate();
    }
    
    class CustomLocalizationsDelegate
        extends LocalizationsDelegate<CustomLocalizations> {
      // 当前本地化,是否在有效的语言范围内
      @override
      bool isSupported(Locale locale) {
        return ['en', 'zh'].contains(locale.languageCode);
      }
    
      // 语言发生变更时,加载对应的本地化资源
      @override
      // Future<CustomLocalizations> load(Locale locale) {
      //   return SynchronousFuture(CustomLocalizations(locale));
      // }
      Future<CustomLocalizations> load(Locale locale) async {
        CustomLocalizations localizations = CustomLocalizations(locale);
        await localizations.loadJson();
        return localizations;
      }
    
      // 本地化重新构建时,是否调用 load 方法,加载本地化资源
      @override
      bool shouldReload(covariant LocalizationsDelegate<CustomLocalizations> old) {
        return false;
      }
    }

    (4)、重新启动应用,切换语言,查看效果

  • 相关阅读:
    小程序那些坑
    2018-5-31 项目总结
    Android AndroidManifest学习笔记
    android 快捷键
    android的liveview装载数据
    android xml产生和解析
    SerializableMaplist传递数据
    android hander 线程用法
    DataGridView实现分页
    DataGridView添加另外一个控件。
  • 原文地址:https://www.cnblogs.com/rogerwu/p/16426773.html
Copyright © 2020-2023  润新知