Flutter-国际化

作者: cg1991 | 来源:发表于2019-05-17 18:23 被阅读16次

    可以参考flutter中文社区的做法:
    https://flutterchina.club/tutorials/internationalization/
    本文参考,但有自己的修改:https://www.didierboelens.com/2018/04/internationalization---make-an-flutter-application-multi-lingual/
    国际化还可以使用IDE插件:https://github.com/long1eu
    文章同步至微信公众号:Android部落格

    一、添加需要支持的库

    在pubspec.yaml中的dependencies:节点下添加依赖:

    flutter_localizations:
      sdk: flutter
    

    同时在程序运行的main.dart中添加import:

    import 'package:flutter_localizations/flutter_localizations.dart';
    

    二、TranslationsDelegate

    添加一个TranslationsDelegate继承自LocalizationsDelegate<Translations>,然后实现这个类的方法:

    class TranslationsDelegate extends LocalizationsDelegate<Translations> {
      const TranslationsDelegate();
    
      /// 改这里是为了不硬编码支持的语言
      @override
      bool isSupported(Locale locale) =>
          supportedLanguages.indexOf(locale.languageCode) >= 0;
    
      @override
      Future<Translations> load(Locale locale) {
        print("load is called");
        return Translations.load(locale);
      }
    
      @override
      bool shouldReload(TranslationsDelegate old) => false;
    
      static const List<String> supportedLanguages = ['en', 'zh'];
    
      Iterable<Locale> supportedLocales() =>
          supportedLanguages.map<Locale>((lang) => new Locale(lang, ''));
    }
    

    再添加一个翻译资源的处理类:

    class Translations {
      Translations(Locale locale) {
        this.locale = locale;
        _localizedValues = null;
      }
    
      Locale locale;
      static Map<dynamic, dynamic> _localizedValues;
    
      static Translations of(BuildContext context) {
        return Localizations.of<Translations>(context, Translations);
      }
    
      String text(String key) {
        print("start apply text");
        return _localizedValues[key] ?? '** $key not found';
      }
    
      static Future<Translations> load(Locale locale) async {
        Translations translations = new Translations(locale);
        String jsonContent =
            await rootBundle.loadString("locale/${locale.languageCode}.json");
        _localizedValues = json.decode(jsonContent);
        return translations;
      }
    
      get currentLanguage => locale.languageCode;
    }
    

    三、在工程根目录下添加资源文件

    在项目根目录下新建locale文件夹,并添加两个翻译资源文件:

    en.json
    {
      "app_title": "My Application Title",
      "main_title": "My Main Title"
    }
    zh.json
    {
      "app_title": "应用程序标题",
      "main_title": "我的主应用"
    }
    

    在pubspec.yaml下声明翻译资源文件:

    assets:
      - locale/en.json
      - locale/zh.json
    

    四、实现主程序的逻辑,跟踪语言的变化:

    import 'package:flutter/material.dart';
    import 'translations.dart';
    import 'package:flutter_localizations/flutter_localizations.dart';
    
    void main() => runApp(new MyApp());
    
    /// 将App设置为Stateful,这让它可以响应刷新事件,调用应用的SetState()
    class MyApp extends StatefulWidget {
      @override
      _MyAppState createState() => new _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      TranslationsDelegate _localeOverrideDelegate = new TranslationsDelegate();
    
      onLocaleChange(Locale locale) {
        setState(() {
          _localeOverrideDelegate = new TranslationsDelegate();
        });
      }
    
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          title: 'My Application',
          theme: new ThemeData(
            primarySwatch: Colors.blue,
          ),
          localizationsDelegates: [
            _localeOverrideDelegate, // 注册一个新的delegate
            GlobalMaterialLocalizations.delegate,
            GlobalWidgetsLocalizations.delegate,
          ],
          supportedLocales: _localeOverrideDelegate.supportedLocales(),
          home: new MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      _MyHomePageState createState() => new _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          appBar: new AppBar(
            title:
                new Text(Translations.of(context).text('main_title')), 
          ),
          body: new Container(),
        );
      }
    }
    

    可以看到比较核心的代码片段是:

    localizationsDelegates: [
            _localeOverrideDelegate, // 注册一个新的delegate
            GlobalMaterialLocalizations.delegate,
            GlobalWidgetsLocalizations.delegate,
          ],
    

    注册系统语言变化的回调到代理类,可以重新加载对应预压的资源然后再去刷新界面,加载对应的多语言资源。

    微信公众号二维码:


    image

    相关文章

      网友评论

        本文标题:Flutter-国际化

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