Flutter 中的国际化之多语言环境

更多文章请查看 flutter从入门 到精通

Flutter 从入门实践到开发一个APP之UI基础篇 教程

本文章将综述:

  • flutter 应用通过 MaterialApp 设置言本地化
  • flutter 应用通过 MaterialApp 配制多语言国际化支持

本文章的终极效果:
在这里插入图片描述


通常我们新建的 Flutter 应用是默认不支持多语言的,即使用户在中文环境下,显示的文字仍然是英文,接下来我们将一步步将系统的这些组件国际化。

1 添加依赖

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter

然后 运行

flutter packages get

以获取依赖

2 在 main.dart 中 import


import 'package:flutter_localizations/flutter_localizations.dart';
3 配置

在 MaterialApp 中配制

import 'package:flutter/material.dart';
import 'package:flutter_mo_study_ui/select_language_page.dart';
import 'package:flutter/foundation.dart';
import 'localizations_delegates.dart';
import 'package:flutter_localizations/flutter_localizations.dart';

void main() => runApp(MyAppThem2());

///创建key值,就是为了调用外部方法
///ChangeLocalizationsState 用来应用内切换语言环境的类
GlobalKey<ChangeLocalizationsState> changeLocalizationStateKey = new GlobalKey<ChangeLocalizationsState>();

class MyAppThem2 extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      ///android 应用任务栏显示的标题
//      title: 'Flutter MU KE DEMO',
      home: new Builder(builder: (context) {
        ///通过 Localizations.override 包裹一层。---这里
        ///将 ChangeLocalizations 使用到 MaterialApp 中
        return new ChangeLocalizations(
          key: changeLocalizationStateKey,
          child: new SelectLanguagePage(),
        );
      }),
      /// 此处 配制多语言环境
      ///配置 android 应用任务栏显示的标题 的国际化
      ///因为 DemoLocalizations 使用到了context 所以这里不使用title 属性
      onGenerateTitle: (context) {
        ///根据语言环境来获取 taskTitle
        ///DemoLocalizations 为自定义的语言文字适配中心
        return DemoLocalizations.of(context).taskTitle;
      },
      ///本地化委托,用于更改Flutter Widget默认的提示语,按钮text等
      ///通常我们新建的 Flutter 应用是默认不支持多语言的,即使用户在中文环境下,显示的文字仍然是英文
      localizationsDelegates: [
        ///初始化默认的 Material 组件本地化
        GlobalMaterialLocalizations.delegate,
        ///初始化默认的 通用 Widget 组件本地化
        GlobalWidgetsLocalizations.delegate,
        ///初始化自定义多语言环境运行
        MyLocalizationsDelegates.delegate,
      ],

      ///当前区域,如果为null则使用系统区域一般用于语言切换
      ///传入两个参数,语言代码,国家代码
      ///这里配制为中国
      locale: Locale('zh', 'CN'),

      ///传入支持的语种数组
      supportedLocales: [
        const Locale('en', 'US'), // English 英文
        const Locale('he', 'IL'), // Hebrew 西班牙
        const Locale('zh', 'CN'), // 中文,后面的countryCode暂时不指定
      ],

      ///当传入的是不支持的语种,可以根据这个回调,返回相近,并且支持的语种
      localeResolutionCallback: (local, support) {
        ///当前软件支行的语言 也就是[supportedLocales] 中配制的语种
        if (support.contains(local)) {
          print('support  $local');
          return local;
        }
        ///如果当前软件运行的手机环境不在 [supportedLocales] 中配制的语种范围内
        ///返回一种默认的语言环境,这里使用的是中文
        print('no_support local is $local and support is $support');
        return const Locale('zh', 'CN');
      },
    );
  }
}

//自定义类 用来应用内切换
class ChangeLocalizations extends StatefulWidget {
  final Widget child;

  ChangeLocalizations({Key key, this.child}) : super(key: key);

  @override
  ChangeLocalizationsState createState() => ChangeLocalizationsState();
}

class ChangeLocalizationsState extends State<ChangeLocalizations> {
  //初始是中文
  Locale _locale = const Locale('zh', 'CH');

  changeLocale(Locale locale) {
    setState(() {
      _locale = locale;
    });
  }

  //通过Localizations.override 包裹我们需要构建的页面
  @override
  Widget build(BuildContext context) {
    //通过Localizations 实现实时多语言切换
    //通过 Localizations.override 包裹一层。---这里
    return new Localizations.override(
      context: context,
      locale: _locale,
      child: widget.child,
    );
  }
}

对于类 MyLocalizationsDelegates

import 'dart:ui';

import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';


///自定义多语言处理代理
class MyLocalizationsDelegates
    extends LocalizationsDelegate<DemoLocalizations> {
  ///构造
  const MyLocalizationsDelegates();
  ///静态构造
  static MyLocalizationsDelegates delegate = const MyLocalizationsDelegates();

  @override
  bool isSupported(Locale locale) {
    return ['en', 'zh', 'he'].contains(locale.languageCode);
  }

  @override //是否需要重载
  bool shouldReload(LocalizationsDelegate old) => false;

  ///MyLocalizations就是在此方法内被初始化的
  ///通过方法的 locale 参数,判断需要加载的语言,然后返回自定义好多语言实现类MyLocalizations
  ///最后通过静态 delegate 对外提供 LocalizationsDelegate。
  @override
  Future<DemoLocalizations> load(Locale locale) {
    //加载本地化
    return new SynchronousFuture(new DemoLocalizations(locale));
  }
}

对于 DemoLocalizations 是配置 具体的文字内容


///Localizations类 用于语言资源整合
class DemoLocalizations {
  ///该Locale类是用来识别用户的语言环境
  /// 在MyLocalizationsDelegates 的load方法中初始化的
  final Locale locale;

  DemoLocalizations(this.locale);


  ///此处通过静态方式来初始化
  static DemoLocalizations of(BuildContext context) {
    ///Localizations 是多国语言资源的汇总
    return Localizations.of(context, DemoLocalizations);
  }

  //根据不同locale.languageCode 加载不同语言对应
  static Map<String, Map<String, String>> _localizedValues = {
    'en': {
      'task title': 'Flutter Demo',
      'titlebar title': 'Flutter Demo Home Page',
      'click tip': 'You have pushed the button this many times:',
      'inc': 'Increment',
      'click button': 'click select language',
      'welcomes': 'China welcomes you'
    },
    'zh': {
      'task title': 'Flutter 示例',
      'titlebar title': 'Flutter 示例主页面',
      'click tip': '你一共点击了这么多次按钮:',
      'inc': '增加',
      'click button': '点击切换',
      'welcomes': '中国欢迎你'
    },
    'he': {
      'task title': 'Ejemplo de Flutter',
      'titlebar title': 'Flutter 示例主页面',
      'click tip': 'Has hecho clic en los botones tantas veces en total:',
      'inc': '增加',
      'click button': 'Haga clic en cambiar',
      'welcomes': 'Bienvenido a China'
    }
  };

  get taskTitle {
    Map<String, String> map = _localizedValues[locale.languageCode];
    return map['task title'];
  }

  get titleBarTitle {
    return _localizedValues[locale.languageCode]['titlebar title'];
  }

  get clickButtonTitle {
    return _localizedValues[locale.languageCode]['click button'];
  }

  get clickTop {
    return _localizedValues[locale.languageCode]['click tip'];
  }

  get inc {
    return _localizedValues[locale.languageCode]['inc'];
  }
  get welcomes {
    return _localizedValues[locale.languageCode]['welcomes'];
  }

}

SelectLanguagePage 页面中 点击按钮实现应用内切换当前语言环境

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_mo_study_ui/localizations_delegates.dart';
import 'package:flutter_mo_study_ui/second_page.dart';

import 'main_language.dart';

/**
 * 多语言切换
 */
class SelectLanguagePage extends StatefulWidget {
  SelectLanguagePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<SelectLanguagePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        ///多种语言支持的导航栏标题
        title: Text(DemoLocalizations.of(context).titleBarTitle),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ///多种语言支持的显示文本
            Text(DemoLocalizations.of(context).welcomes,style: TextStyle(color: Colors.red,fontSize: 22),),
            Padding(
              padding: EdgeInsets.all(30),
            ),
            ///点击按钮显示语言选择框
            FlatButton(
              child: Text(DemoLocalizations.of(context).clickButtonTitle),
              onPressed: () {
                changeLocale();
              },
            )
          ],
        ),
      ),
    );
  }


  ///语言切换
  ///这里则是弹框内容了
  void changeLocale(){
    showDialog(
      context: context,
      barrierDismissible: false,//// user must tap button!
      builder: (BuildContext context) {
        return new SimpleDialog(
          title: new Text("请选择语言"),
          children: <Widget>[
            SimpleDialogOption(
              onPressed: () {
                switchLanguage(0);
                Navigator.of(context).pop();
              },
              child: const Text("中文"),
            ),
            SimpleDialogOption(
              onPressed: () {
                switchLanguage(1);
                Navigator.of(context).pop();
              },
              child: const Text("英语"),
            ),
            SimpleDialogOption(
              onPressed: () {
                switchLanguage(2);
                Navigator.of(context).pop();
              },
              child: const Text("西班牙语"),
            )
          ],
        );
      },
    );
  }

  ///切换语言
  ///通过 changeLocalizationStateKey 来修改本应用内的 Locale
  void switchLanguage(int index) {
    switch(index){
      case 0:
        changeLocalizationStateKey.currentState.changeLocale(const Locale('zh','CH'));
        break;
      case 1:
        changeLocalizationStateKey.currentState.changeLocale(const Locale('en','US'));
        break;
      case 2:
        changeLocalizationStateKey.currentState.changeLocale(const Locale('he', 'IL'));
        break;
    }
  }
}

发布了354 篇原创文章 · 获赞 180 · 访问量 45万+

猜你喜欢

转载自blog.csdn.net/zl18603543572/article/details/103606416