美文网首页Flutter
Flutter(9)-i18n的国际化使用和Provider的简

Flutter(9)-i18n的国际化使用和Provider的简

作者: BoxJing | 来源:发表于2019-10-23 18:18 被阅读0次

    本篇文章介绍介绍一下,在Flutter中如何使用i18n来进行国际化和用Provider来简单的进行状态管理。

    1. i18n国际化

    开发工具使用Android Studio,如图在Preferences->Plugins中搜索i18n进行插件安装,安装完后,新建的flutter项目会自带i18n.dartarb文件。

    i18n插件安装.png

    res->values中我们可以新建需要支持的国家的Arb文件。

    新建Arb文件.jpg
    然后我们就可以在对应的arb文件中,写对应的键值对,和iOS的国际化一毛一样。
    添加key-value.jpg
    i18n.dart的文件中已经说明该文件完全自动生成的,用户的更改会被放弃,我们会发现我们修改了arb的键值对后,i18n文件会自动生成一些代码,完全不用我们再去更改,也不允许我们更改。
    i18n文件.jpg
    然后我们需要在MaterialApp里面使用localeResolutionCallback: (Locale locale, Iterable<Locale> supported)这个回调拿到当前系统的语言,然后返回对应的国际化语言,里面需要返回一个对应的Local对象,当返现我们APP内没有对应的国际化的时候,就需要我们返回一个合适的存在的Local对象。
    localeResolutionCallback: (Locale locale, Iterable<Locale> supported) {
              bool isSupported(Locale locale) {
                if (locale == null) return false;
                if (supported.contains(locale)) {
                  return true;
                } else {
                  for (Locale supportedLocale in supported) {
                    if (supportedLocale.countryCode == null || supportedLocale.countryCode.isEmpty)
                      if (supportedLocale.languageCode == locale.languageCode) return true;
                  }
                  return false;
                }
              }
              if (!isSupported(locale))
                return supported.first;
              final Locale languageLocale = Locale(locale.languageCode, "");
              if (supported.contains(locale)) return locale;
              else if (supported.contains(languageLocale)) return languageLocale;
              else return supported.first;
            },
    

    在对应的地方取值S.of(context).app_information,可能你会发现没跟着系统走,对应的平台工程需要设置一下语言的支持,iOS如下:

    工程设置语言支持.png
    到此,使用i18n插件根据系统语言进行国际化就完成了。

    2. Provider

    pubsepec.yaml中添加provider: ^3.1.0,然后packages get添加provider的引入,provider作为谷歌的亲儿子,使用起来也觉得挺方便,在开发的过程中可以替代掉stateless类型的Widget,根据需要进行刷新。
    新建一个类作为数字的管理类,在需要通知刷新的地方调用notifyListeners()

    import 'package:flutter/cupertino.dart';
    
    class BoxProvider extends ChangeNotifier {
      int _index = 0;
      void setIndex(int index) {
        if (_index != index) {
          _index = index;
          debugPrint('通知刷新');
          notifyListeners();
        }
      }
      int index () {
        return _index;
      }
      void changeIndex() {
        debugPrint('改变');
        setIndex(_index+1);
      }
    }
    

    由于需要跨界面来实现,所以我们需要在顶层进行Provider的注册:

    MultiProvider(
          providers:[
            ChangeNotifierProvider<BoxProvider>(
              builder: (context) => BoxProvider(),
            ),
          ],
          child: MaterialApp(
          ...
    

    然后在需要更新的地方进行Consumer,在收到notifyListeners()之后,此处会重新builder来构建界面:

    Consumer<BoxProvider>(
                  builder: (context,model,_){
                    return Text(
                      model.index().toString(),
                    );
                  },
                ),
    

    注册在顶层,这样的话我们可以在任何的一个页面进行改变的操作:

    Provider.of<BoxProvider>(context).changeIndex();
    

    看一下效果:


    小Demo源码已经放在Github: i18n&Provider中。

    相关文章

      网友评论

        本文标题:Flutter(9)-i18n的国际化使用和Provider的简

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