Flutter

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

2019-10-23  本文已影响0人  BoxJing

本篇文章介绍介绍一下,在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中。
上一篇下一篇

猜你喜欢

热点阅读