美文网首页Flutter入坑
[Flutter]实现i18n,运行时切换简繁英

[Flutter]实现i18n,运行时切换简繁英

作者: lisjiang | 来源:发表于2019-01-28 19:16 被阅读219次

    一、导包

    引入“flutter_localizations包”,并且“flutter packages get”:

    dependencies:
    
      ...
    
      flutter_localizations:
    
        sdk: flutter
    

    二、添加协议以及支持语言

    import 'package:flutter_localizations/flutter_localizations.dart';
    ...
    return MaterialApp(
          ...
          localizationsDelegates: [
            GlobalMaterialLocalizations.delegate,
            GlobalWidgetsLocalizations.delegate,
          ],
          supportedLocales: [
            const Locale('zh', 'CN'),
            const Locale('zh', 'HK'),
            const Locale('zh', 'TW'),
            const Locale('en', 'US'),
          ],
        );//MaterialApp
    

    三、编写Localizations类

    Localizations汇总所有翻译文本

    import 'package:flutter/material.dart';
    
    class  MyLocalizations {
      final Locale locale;
    
      MyLocalizations(this.locale);
    
      static Map<String, Map<String, String>> _localizedValuesMap = {
        'en_US': {
          'test_text': 'Test Text',
        },
        'zh_CN': {
          'test_text': '测试文字',
        },
        'zh_HK': {
          'test_text': '測試文字',
        },
        'zh_TW': {
          'test_text': '測試文字',
        }
      };
    
      get testText{
        ///注意用 locale.toString()而非locale
        return _localizedValuesMap[locale.toString()]['test_text'];
      }
    
      ///MyLocalizations的实例是在 Localizations中通过 MyLocalizationsDelegate实例化,
      ///应用中要使用 MyLocalizations的实例需要通过 Localizations这个 Widget来获取。
      static MyLocalizations of(BuildContext context){
        return Localizations.of(context, MyLocalizations);
      }
    }
    

    四、实现LocalizationsDelegate协议,用于初始化Localizations类

    import 'package:flutter/foundation.dart';
    import 'package:flutter/material.dart';
    import 'package:gd_i18n_project/MyLocalizations.dart';
    
    class MyLocalizationsDelegate extends LocalizationsDelegate<MyLocalizations>{
      const MyLocalizationsDelegate();
      static MyLocalizationsDelegate delegate = const MyLocalizationsDelegate();
    
      @override
      bool isSupported(Locale locale) {
        return ['en','zh'].contains(locale.languageCode);
      }
    
      @override
      Future<MyLocalizations> load(Locale locale) {
        ///这里初始化 Localizations类
        return SynchronousFuture<MyLocalizations>(new MyLocalizations(locale));
      }
    
      @override
      bool shouldReload(LocalizationsDelegate<MyLocalizations> old) {
        return false;
      }
    }
    

    添加到"localizationsDelegates":

    return MaterialApp(
          ...
          localizationsDelegates: [
            GlobalMaterialLocalizations.delegate,
            GlobalWidgetsLocalizations.delegate,
            ///自定义 LocalizationsDelegate协议;
            MyLocalizationsDelegate(),
          ],
          ...
        );///MaterialApp
    

    五、替换应用的Title

    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          onGenerateTitle: (context){
            //默认的 build()的 context对象无法获得 MyLocalizations对象,
            //所以这里引用 onGenerateTitle的 context对象。
            return MyLocalizations.of(context).testText;
          },
    ...
    

    六、替换MyHomePage的Title

     Widget build(BuildContext context) {
        return MaterialApp(
          ...
          //修改MyHomePage()的构造函数,去掉title
          home: MyHomePage(),
          ...
    
    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            //同第五步,默认的 build()的 context对象无法获得 MyLocalizations对象。
            title: Text(MyLocalizations.of(context).testText),
          ),
          ...
    

    到这一步应用能跟随系统更改语言。


    七、运行时更改语言

    import 'package:flutter/material.dart';
    
    ///用于操作子widget运行时更改语言
    class MyI18nWidget extends StatefulWidget {
      final child;
      MyI18nWidget({this.child, Key key}):super(key:key);
    
      @override
      State<StatefulWidget> createState() => MyI18nWidgetState();
    }
    
    class MyI18nWidgetState extends State<MyI18nWidget> {
      var _locale;
    
      @override
      void didChangeDependencies() {
        super.didChangeDependencies();
        //获取当前设备语言
        _locale = Localizations.localeOf(context);
      }
    
      ///动态切换子widget的语言
      void changeLanguage(Locale locale){
        setState(() {
          _locale=locale;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Localizations.override(
          context: context,
          locale: _locale,
          child: widget.child,
        );
      }
    }
    
    void main() => runApp(MyApp());
    ///用于外部获取MyI18nWidgetState来调用其changeLanguage();
    GlobalKey<MyI18nWidgetState> myI18nWidgetStateKey=GlobalKey<MyI18nWidgetState>();
    class MyApp extends StatelessWidget {
    ...
    }
    
    return MaterialApp(
          ...
          //MyI18nWidget作为MyHomePage的父widget
          home: MyI18nWidget(
            key: myI18nWidgetStateKey,
            child: MyHomePage(
            ),
          ),
          ...
    )//MaterialApp
    
    //指定地方调用,动态更改语言
    myI18nWidgetStateKey.currentState.changeLanguage(Locale('en','US'));
    

    参考

    《Flutter 中的国际化》_番茄沙司 https://www.jianshu.com/p/8356a3bc8f6c

    相关文章

      网友评论

        本文标题:[Flutter]实现i18n,运行时切换简繁英

        本文链接:https://www.haomeiwen.com/subject/ubfvjqtx.html