美文网首页Flutter
Flutter国际化的三种方式-->json

Flutter国际化的三种方式-->json

作者: 谢尔顿 | 来源:发表于2019-08-26 10:29 被阅读0次

    关于Flutter的国际化有三种实现方式,本文主要讲述的是使用flutter_localizations的实现方式。
    下面是我们最终实现的效果图:


    1. 项目结构


    2.代码分析
    assets/i18n下的两个json文件,是我们翻译中分别用到的源文件,en.json和zh.json的源码如下所示:

    en.json:

    {
      "hello": "Hello!",
      "greetTo": "Nice to meet you,{{name}}!",
      "app_title":"Flutter Internationalization",
      "jump_to_second_page": "Jump to the second page",
      "second_page": "Second page",
      "switch": "Switch"
    }
    

    zh.json

    {
      "hello": "你好!",
      "greetTo": "{{name}},见到你很高兴!",
      "app_title":"Flutter国际化",
      "jump_to_second_page": "跳转到第二个界面",
      "second_page": "第二个界面",
      "switch": "切换"
    }
    

    翻译资源json准备完之后,在pubspec.yaml中添加所需要的依赖,如下图所示:


    红框的部分就是我们项目所以需要的。

    initialize_i18n.dart文件是用来加载assets/i18n下的json资源的:

    import 'dart:convert';
    
    import 'package:flutter/services.dart';
    
    import 'constant.dart' show languages;
    
    //加载json资源
    Future<String> loadJsonFromAsset(language) async {
      return await rootBundle.loadString('assets/i18n/' + language + '.json');
    }
    
    Map<String, String> convertValueToString(obj) {
      Map<String, String> result = {};
      obj.forEach((key, value) {
        result[key] = value.toString();
      });
      return result;
    }
    
    Future<Map<String, Map<String, String>>> initializeI18n() async {
      Map<String, Map<String, String>> values = {};
      for (String language in languages) {
        Map<String, dynamic> translation =
            json.decode(await loadJsonFromAsset(language));
        values[language] = convertValueToString(translation);
      }
    
      return values;
    }
    

    localizations.dart文件:

    import 'package:flutter/foundation.dart';
    import 'package:flutter/material.dart';
    
    import 'constant.dart';
    
    //调用该类获取字符串内容
    class MyLocalizations {
      final Map<String, Map<String, String>> localizedValues;
      final Locale locale;
    
      MyLocalizations(this.locale, this.localizedValues);
      static MyLocalizations of(BuildContext context) {
        return Localizations.of<MyLocalizations>(context, MyLocalizations);
      }
    
      String get hello {
        return localizedValues[locale.languageCode]['hello'];
      }
    
      greetTo(name) {
        return localizedValues[locale.languageCode]['greetTo']
            .replaceAll('{{name}}', name);
      }
    
      String get homeTitle {
        return localizedValues[locale.languageCode]['app_title'];
      }
    
      String get jumpToSecondPage {
        return localizedValues[locale.languageCode]['jump_to_second_page'];
      }
    
      String get secondPage {
        return localizedValues[locale.languageCode]['second_page'];
      }
    
      String get qh {
        return localizedValues[locale.languageCode]['switch'];
      }
    }
    
    class MyLocalizationsDelegate extends LocalizationsDelegate<MyLocalizations> {
      Map<String, Map<String, String>> localizedValues;
      MyLocalizationsDelegate(this.localizedValues);
      @override
      bool isSupported(Locale locale) => languages.contains(locale.languageCode);
    
      @override
      Future<MyLocalizations> load(Locale locale) {
        return SynchronousFuture<MyLocalizations>(
            MyLocalizations(locale, localizedValues));
      }
    
      @override
      bool shouldReload(LocalizationsDelegate<MyLocalizations> old) {
        return false;
      }
    }
    

    MyLocalizationsDelegate中的languges来自于constant.dart.

    List<String> languages=['en','zh'];
    

    最后,在main.dart中将上面的每个部分连接起来:

    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    import 'package:flutter_localizations/flutter_localizations.dart';
    
    import 'constant.dart';
    import 'initialize_i18n.dart';
    import 'localizations.dart';
    import 'pages/second_page.dart';
    
    //import 'package:url_launcher/url_launcher.dart';
    
    void main() async {
      //加载中英文数据源
      Map<String, Map<String, String>> localizedValues = await initializeI18n();
    
      runApp(MyApp(localizedValues));
    }
    
    class MyApp extends StatefulWidget {
      final Map<String, Map<String, String>> localizedValues;
      MyApp(this.localizedValues);
      @override
      _MyAppState createState() => _MyAppState();
    }
    
    class _MyAppState extends State<MyApp> {
      String _locale = 'en';
      //切换语言
      onChangeLanguage() {
        if (_locale == 'en') {
          setState(() {
            _locale = 'zh';
          });
        } else {
          setState(() {
            _locale = 'en';
          });
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          localizationsDelegates: [
            MyLocalizationsDelegate(widget.localizedValues),//设置自己定义的代理
            GlobalMaterialLocalizations.delegate,
            GlobalWidgetsLocalizations.delegate,
            GlobalCupertinoLocalizations.delegate,//用于兼容ios
          ],
          locale: Locale(_locale),//设置当前的语言
          supportedLocales: languages.map((language) => Locale(language, '')),
          home: MyHomePage(onChangeLanguage),
        );
      }
    }
    
    class MyHomePage extends StatelessWidget {
      final VoidCallback onChangeLanguage;
      MyHomePage(this.onChangeLanguage);
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: new AppBar(
            title: new Text(MyLocalizations.of(context).homeTitle),
          ),
          body: Container(
            width: MediaQuery.of(context).size.width,
            padding: EdgeInsets.only(top: 30),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.center,
              mainAxisSize: MainAxisSize.max,
              children: <Widget>[
                Text(MyLocalizations.of(context).greetTo('胡歌')),
                SizedBox(
                  height: 20.0,
                ),
                Container(
                  width: 200.0,
                  height: 40.0,
                  child: FlatButton(
                      color: Colors.lightBlue,
                      onPressed: () {
                        Navigator.of(context)
                            .push(MaterialPageRoute(builder: (cxt) {
                          return SecondPage();
                        }));
                      },
                      child: Text(
                        MyLocalizations.of(context).jumpToSecondPage,
                        style: TextStyle(color: Colors.white),
                      )),
                ),
              ],
            ),
          ),
          floatingActionButton: new FloatingActionButton(
              child: Text(MyLocalizations.of(context).qh),
              onPressed: onChangeLanguage),
        );
      }
    }
    

    在main.dart中,我们可以直接利用MyLocalizations.of(context).homeTitle等给对应的字符串赋值。点击按钮切换时,只需要切换MaterialApp中locale的值即可。

    相关文章

      网友评论

        本文标题:Flutter国际化的三种方式-->json

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