美文网首页Android技术知识Flutter中文社区Flutter
Flutter - International 国际化,Loca

Flutter - International 国际化,Loca

作者: AnRFDev | 来源:发表于2018-07-16 08:54 被阅读77次

    记录一种简单的方式实现字符串的国际化。
    这里没有用到Intl包,而是将所需的字符串存放在一个map中。

    步骤:

    • MaterialApp中添加本地化代理和语言类型
    • 创建文字资源文件
    • 新建一个类继承LocalizationsDelegate,和文字资源文件联系起来
    • 使用代理获取想要的文字资源

    新建项目international_demo,得到一个带按钮示例工程。改造一下MaterialApp

    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          title: 'Flutter Demo',
          theme: new ThemeData(
            primarySwatch: Colors.blue,
          ),
          localizationsDelegates: [// 添加区域
            // 准备在这里添加我们自己创建的代理
            GlobalMaterialLocalizations.delegate,
            GlobalWidgetsLocalizations.delegate,
          ],
          supportedLocales: [ // 添加区域
            const Locale('en', 'US'), // English
            const Locale('he', 'IL'), // Hebrew
            // 可以继续添加我们想要支持的语言类型
          ],
          home: new MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    

    创建资源文件

    新建localization_src.dart,将字符串存入一个map中。

    import 'package:flutter/material.dart';
    
    class DemoLocalizations {
      DemoLocalizations(this.locale);
    
      final Locale locale;
    
      static DemoLocalizations of(BuildContext context) {
        return Localizations.of<DemoLocalizations>(context, DemoLocalizations);
      }
    
      static Map<String, Map<String, String>> _localizedValues = {
        'en': {
          'title': 'Hello World',
        },
        'es': {
          'title': 'Hola Mundo',
        },
        'zh': {
          'title': '你好呀',
        },
      };
    
      String get title {
        return _localizedValues[locale.languageCode]['title'];
      }
    }
    

    这里仅以title为例,有英语、西班牙语和中文三种。

    创建代理

    新建一个类继承LocalizationsDelegate,复写3个方法。

    import 'dart:async';
    
    import 'package:flutter/foundation.dart';
    import 'package:flutter/material.dart';
    import 'package:international_demo/localization_src.dart';
    
    class DemoLocalizationsDelegate
        extends LocalizationsDelegate<DemoLocalizations> {
      const DemoLocalizationsDelegate();
    
      @override
      bool isSupported(Locale locale) =>
          ['en', 'es', 'zh'].contains(locale.languageCode);
    
      @override
      Future<DemoLocalizations> load(Locale locale) {
        return SynchronousFuture<DemoLocalizations>(DemoLocalizations(locale));
      }
    
      @override
      bool shouldReload(DemoLocalizationsDelegate old) => false;
    }
    

    复写的load方法中,使用了SynchronousFuture

    使用代理

    回到main.dart

    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          title: 'Flutter Demo',
          theme: new ThemeData(
            primarySwatch: Colors.blue,
          ),
          localizationsDelegates: [
            DemoLocalizationsDelegate(),// 这是我们新建的代理
            GlobalMaterialLocalizations.delegate,
            GlobalWidgetsLocalizations.delegate,
          ],
          supportedLocales: [
            const Locale('en', 'US'), // English
            const Locale('he', 'IL'), // Hebrew
            const Locale('zh', ''),   // 新添中文,后面的countryCode暂时不指定
          ],
          home: new MyHomePage(title: 'Flutter Demo Home Page'),
        );
      }
    }
    

    _MyHomePageState中调用DemoLocalizations

        DemoLocalizations localizations = DemoLocalizations.of(context);
        print(localizations); // 打印出 I/flutter (25535): Instance of 'DemoLocalizations'
    

    观察logcat,可知我们获得了DemoLocalizations的实例。

    获取title

    DemoLocalizations.of(context).title
    

    如果需要更多的字符串,需要我们手动在资源文件的map中添加。
    这里仅以title为例。

    文件

    参考:

    相关文章

      网友评论

      • 游泳帽:ios模拟器切换语言 位置啥的都没用 一直读取en的值 安卓模拟器是可以的
        游泳帽:谢谢楼主的解答:pray:
        AnRFDev:本文开发环境是win7,测试用的是安卓手机(荣耀和红米)。iOS模拟器没有试过:joy:
        但在github issue上可以看到相关的问题: https://github.com/flutter/flutter/issues/14128
        国内外很多开发者遇到了类似的问题。大体有几个思路:
        1. 换用iPhone或者iPad试试,用真机看看效果;
        2. 在XCode的flutter工程中,打开Info栏,选择Localizations,添加想要的语言类型;(Sonius94的建议)
        3. MaterialApp中添加localeResolutionCallback
        localeResolutionCallback: (Locale locale,
        Iterable<Locale> supportedLocales) {
        for (var supportedLocale in supportedLocales) {
        if (locale.countryCode == supportedLocale.countryCode) {
        return supportedLocale;
        }
        }
        return locale;
        },

      本文标题:Flutter - International 国际化,Loca

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