Avatar
😀

Organizations

2 results for Flutter
  • Flutter里的国际化,简言之,分为两大步:

    1. 创建本地化资源。
    2. 创建本地化资源代理,并配置到APP入口函数。

    应用内切换语言,关键点有两个:

    1. 指定应用的语言:设置 MaterialApp 的 locate 参数。
    2. 取得当前语言对应的本地化资源文件:Localizations.of<S>(context, S)

    Localizations 继承自 StatefulWidget ,内部属性 locale 有变化,child 就会重建。

    以下,为国际化代码的具体实现:

    前提

    pubspec.yaml 文件中添加它和 intl作为依赖

    flutter pub add flutter_localizations --sdk=flutter
    flutter pub add intl:any
    

    最终的 pubspec.yaml 文件中形如:

    dependencies:
      flutter:
        sdk: flutter
      flutter_localizations:
        sdk: flutter
      intl: any
    

    1. 创建本地化资源

    1.1 创建本地化资源接口,声明需要翻译的字段。

    使用接口定义待翻译字段的好处是:实现类/子类 必须对抽象字段进行赋值,否则编译器会报错。 相比之下,字典的方式,某个 key 没有赋值,编译器检查不出来,而且,哪些 key 是有用的,哪些 key 没用了,也不好确定。

    /// 本地化资源 基类
    abstract class S {
      /// 本地化资源代理对象
      static const LocalizationsDelegate delegate = ProjectLocalizationsDelegate();
    
      /// 根据上下文中的 [Locale] 取得对应的本地化资源。
      static S of(BuildContext context) {
        return Localizations.of<S>(context, S)!;
      }
    
      /// 支持的语言。
      /// 如果本地没有保存的语言配置参数,APP会默认使用第一个作为默认语言。
      static List<Locale> supportedLocales = [
        const Locale('en'),
        const Locale('ja'),
        const Locale('zh')
      ];
    
      // 不需要翻译的字段,直接赋值。
      static String appName = 'AppName';
      static String english = 'English';
      static String japanese = '日本語';
      static String simpleChinese = '简体中文';
      static Map<String, String> localeSets = {
        'en': english,
        'ja': japanese,
        'zh': simpleChinese
      };
    
      // 需要翻译的字段追加到下面,在子类中进行赋值。
      String get cancel;
      String get ok;
      String get readAndAgree;
      String get privacyPolicy;
      String get termsOfService;
    
      String get me;
      String get settingsLanguage;
    }
    

    1.2 创建指定语言的资源类(实现上一步中的接口),对接口中的成员变量进行赋值。

    /// 英文
    class ProjectLocalizationsEN implements S {
      @override
      String get cancel => "Cancel";
    
      @override
      String get ok => "OK";
    }
    
    /// 中文
    class ProjectLocalizationsZH implements S {
      @override
      String get cancel => "取消";
    
      @override
      String get ok => "确定";
    }
    
    /// 日文
    class ProjectLocalizationsJA implements S {
      @override
      String get cancel => "キャンセル";
    
      @override
      String get ok => "確定";
    }
    

    2. 创建本地化资源代理

    2.1 创建本地化资源代理类(继承 LocalizationsDelegate),重写 load 方法,根据 locale 返回对应语言的资源。

    /// 项目本地化资源代理
    class ProjectLocalizationsDelegate extends LocalizationsDelegate<S> {
      const ProjectLocalizationsDelegate();
    
      @override
      bool isSupported(Locale locale) => true;
    
      @override
      Future<S> load(Locale locale) {
        return SynchronousFuture<S>(getMaterialTranslation(locale));
      }
    
      @override
      bool shouldReload(ProjectLocalizationsDelegate old) => false;
    
      /// 根据 locale 得到对应的本地化资源
      S getMaterialTranslation(Locale locale) {
        switch (locale.languageCode) {
          case 'en':
            return ProjectLocalizationsEN();
          case 'zh':
            return ProjectLocalizationsZH();
          case 'ja':
            return ProjectLocalizationsJA();
          default:
            return ProjectLocalizationsEN();
        }
      }
    }
    

    2.2 在程序入口 MaterialApp 中的 localizationsDelegates 参数中,加入自己创建的本地化资源代理类。

    import 'package:flutter_localizations/flutter_localizations.dart';
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Consumer<LocaleStore>(builder: (context, localeStore, _) {
          return OKToast(
            movingOnWindowChange: false,
            child: MaterialApp(
              onGenerateTitle: (context) => S.appName,  // 不需要翻译的字段,可以直接类名调用。
              theme: AppTheme.lightTheme(context),
              localizationsDelegates: const [
                GlobalMaterialLocalizations.delegate,
                GlobalWidgetsLocalizations.delegate,
                // 项目本地化资源代理
                S.delegate,
              ],
              // 支持的语言
              supportedLocales: S.supportedLocales,
              // 指定语言,如果 localStore 里没有保存的语言参数,则直接使用 S 文件中配置的第一个语言。
              locale: localeStore.languageCode == null
                  ? S.supportedLocales.first
                  : Locale(localeStore.languageCode!),
              routes: RouteMap.routes,
              home: const HomePage(),
              builder: (context, child) => GestureDetector(
                onTap: () => CommonUtils.hideKeyboard(context),
                child: child,
              ),
            ),
          );
        });
      }
    }
    

    配置完成,开始使用:

    • 不需要翻译的字段,使用方式: S.appName
    • 支持多语言的字段,使用方式: S.of(context).ok S.of(context). cancel
    Flutter Created Mon, 27 Feb 2023 22:21:33 +0800
  • 功能描述 命令
    安装依赖包 flutter pub get
    检查哪些依赖包过期 flutter pub outdated
    检查项目依赖包是否支持空安全 dart pub outdated --mode=null-safety
    升级依赖包 flutter pub upgrade
    升级依赖包-大版本 flutter pub upgrade --major-versions
    将项目代码迁移到空安全 dart migrate
    自动修复代码问题 dart fix --apply
    打包 Android bundle flutter build appbundle
    打包 Android apks flutter build apk --split-per-abi
    打包 iOS flutter build ios
    Debug 模式运行 flutter run
    Profile 模式运行 flutter run --profile
    Release 模式运行 flutter run --release
    指定 Web 渲染模式 flutter run -d chrome --web-renderer html
    发布包检查 flutter packages pub publish --dry-run
    发布包 flutter packages pub publish --server=https://pub.dartlang.org
    Flutter Created Sat, 12 Feb 2022 15:00:00 +0000