(五)Flutter Redux 中的国际化

在前面(四)Flutter Redux 中实现简单换肤清楚了一个简单的换肤,这次来看下Redux中实现国际化。
自定义国际化的方法有2种:
1、基于Map,该方式要我们自己手动来维护多套语言。
2、基于Intl,该方式是开发人员通过工具将翻译好的arb文件转为代码。
这边主要讲的是基于Map。Intl的网上也有很多文章。

导入库

  flutter_localizations:
    sdk: flutter

自定义国际化需要实现两个类

Delegate类

在Locale改变时加载新的Locale资源,Delegate类需要继承自LocalizationsDelegate类,实现相应的接口。LocalizationsDelegate需要提供一个泛型参数,也就是下面的 自定义的 Localizations 类。

localization_delegate.dart

class FZLocalizationDelegate extends LocalizationsDelegate<MoreLocalization> {

  FZLocalizationDelegate();

  ///是否支持某个Local
  ///支持中文和英语
  @override
  bool isSupported(Locale locale) {
    return ['zh', 'en'].contains(locale.languageCode);
  }

  ///shouldReload的返回值决定当Localizations Widget重新build时,是否调用load方法重新加载Locale资源
  @override
  bool shouldReload(LocalizationsDelegate<MoreLocalization> old) {
    return false;
  }

  ///根据locale,创建一个对象用于提供当前locale下的文本显示
  ///Flutter会调用此类加载相应的Locale资源类
  @override
  Future<MoreLocalization> load(Locale locale) {
    return SynchronousFuture<MoreLocalization>(
        MoreLocalization(locale)
    );
  }

  static FZLocalizationDelegate delegate = FZLocalizationDelegate();
}
Localizations类

提供不同语言的数据。这边的定义方式是提供1个抽象类,接着1个英文1个中文的实现类。

more_localization.dart

class MoreLocalization {

  final Locale locale;
  MoreLocalization(this.locale);

  /// 基于Map,根据当前语言的 languageCode: en或zh来获取对应的文案
  static Map<String, BaseLanguage> _localValue = {
    'en' : EnLanguage(),
    'zh' : ChLanguage()
  };

  /// 返回当前的内容维护类
  BaseLanguage get currentLocalized {
    return _localValue[locale.languageCode];
  }

  ///通过 Localizations.of(context,type) 加载当前的 FZLocalizations
  static MoreLocalization of(BuildContext context) {
    return Localizations.of(context, MoreLocalization);
  }
}

/// 这个抽象类和它的实现类可以拉出去新建类
/// 中文和英语 语言内容维护
abstract class BaseLanguage {
  String name;
}

class EnLanguage implements BaseLanguage {
  @override
  String name = "This is English";
}

class ChLanguage implements BaseLanguage {
  @override
  String name = "这是中文";
}

无Redux,App语言随系统语言变化

main.dart
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_demo/State/Language_NoRedux/first_page.dart';
import 'package:flutter_demo/State/Language_NoRedux/localization_delegate.dart';

main() {
  runApp(ReduxDemo3());
}

class ReduxDemo3 extends StatelessWidget {

  ReduxDemo3();

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'ReduxDemo3',
      localizationsDelegates: [
        /// 本地化的代理类
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        /// 注册我们的Delegate
        FZLocalizationDelegate.delegate
      ],
      supportedLocales: [
        const Locale('en', 'US'), // 美国英语
        const Locale('zh', 'CN'), // 中文简体
      ],
      /// 监听系统语言切换
      localeListResolutionCallback: (deviceLocale, supportedLocales){
        print('deviceLocale: $deviceLocale');
        // 系统语言是英语: deviceLocale: [en_CN, en_CN, zh_Hans_CN]
        // 系统语言是中文: deviceLocale: [zh_CN, zh_Hans_CN, en_CN]
        print('supportedLocales: $supportedLocales');
      },
      home: FirstPage(),
    );
  }
}
first_page.dart
class FirstPageState extends State<FirstPage> {
  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(
        title: Text("ReduxDemo3"),
      ),
      body: Center(
          child: Column(
            children: <Widget>[
              SizedBox(height: 50,),
              Text("MoreLocalization 当前内容:${MoreLocalization.of(context).currentLocalized.name}"),
              SizedBox(height: 50,),
              /// 获取系统当前语言
              Text("Localizations 当前语言:${Localizations.localeOf(context)}"),
            ],
          )
      ),
    );
  }
}
效果

系统语言英文:
在这里插入图片描述
系统语言中文:
在这里插入图片描述

Redux,App语言可在App内手动变更

locale_redux.dart
final LocaleReducer = combineReducers<Locale>([
  TypedReducer<Locale, LocaleRefreshAction>(_refreshLocale)
]);

Locale _refreshLocale(Locale locale, LocaleRefreshAction action) {
  locale = action.locale;
  return locale;
}

class LocaleRefreshAction {
  Locale locale;
  LocaleRefreshAction(this.locale);
}
redux_state.dart
/// 定义一个state
class ReduxState {
  Locale locale;
  ReduxState({this.locale});
}

/// 定义action,将action放到theme_redux类里去定义

/// 定义reducer
ReduxState getReduce(ReduxState state, action) {
  return ReduxState(
    locale: LocaleReducer(state.locale, action)
  );
}
redux_state.dart

这边虽然有给了全局Store默认的语言,但是在下面的 监听系统语言变更回调里 localeListResolutionCallback里有再修改一次。

import 'package:flutter_demo/State/Language_Redux/redux_state.dart';
import 'package:flutter_demo/State/Language_Redux/first_page.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_demo/State/Language_Redux/localization_delegate.dart';
import 'package:flutter_demo/State/Language_Redux/locale_redux.dart';

main() {
  /// 创建全局Store
  final store = Store<ReduxState>(
      getReduce,
      initialState: ReduxState(
        locale: Locale("zh", 'CN')
      )
  );
  runApp(ReduxDemo3(store,));
}

class ReduxDemo3 extends StatelessWidget {

  final Store<ReduxState> store;
  ReduxDemo3(this.store);

  @override
  Widget build(BuildContext context) {
    return StoreProvider(
        store: store,
        /// StoreBuilder后要跟上我们定义的那个State类,要不会报错,
        child: StoreBuilder<ReduxState>(builder: (BuildContext context, Store<ReduxState> store){
          return MaterialApp(
            title: 'ReduxDemo3',
            localizationsDelegates: [
              GlobalMaterialLocalizations.delegate,
              GlobalWidgetsLocalizations.delegate,
              FZLocalizationDelegate.delegate
            ],
            /// 这边设置 locale 主要是为了在项目里手动更改语言,如果是不想手动变更,而是要随系统自动变更可以注释
            locale: store.state.locale,
            supportedLocales: [
              const Locale('en', 'US'), // 美国英语
              const Locale('zh', 'CN'), // 中文简体
            ],
            /// 监听系统语言切换
            localeListResolutionCallback: (deviceLocale, supportedLocales){
              print('deviceLocale: $deviceLocale');
              // 系统语言是英语: deviceLocale: [en_CN, en_CN, zh_Hans_CN]
              // 系统语言是中文: deviceLocale: [zh_CN, zh_Hans_CN, en_CN]
              print('supportedLocales: $supportedLocales');

              /// 系统自动检测到语言后修改Store里的语言
              if (deviceLocale.length > 0) {
                if (store.state.locale.languageCode != deviceLocale[0].languageCode) {
                  store.dispatch(LocaleRefreshAction(deviceLocale[0]));
                }
              }
            },
            home: FirstPage(),
          );
        })
    );
  }
}
first_page.dart
class FirstPageState extends State<FirstPage> {
  @override
  Widget build(BuildContext context) {

    return StoreBuilder<ReduxState>(
        builder: (BuildContext context, Store<ReduxState> store){
          return Scaffold(
            appBar: AppBar(
              title: Text("ReduxDemo3"),
            ),
            body: Center(
                child: Column(
                  children: <Widget>[
                    SizedBox(height: 50,),
                    FlatButton(
                        onPressed: (){
                          store.dispatch(LocaleRefreshAction(Locale('zh','CH')));
                        },
                        child: Text('手动设置APP语言为:中文')
                    ),
                    SizedBox(height: 50,),
                    FlatButton(
                        onPressed: (){
                          store.dispatch(LocaleRefreshAction(Locale('en','US')));
                        },
                        child: Text('手动设置APP语言为:英文')
                    ),
                    SizedBox(height: 50,),
                    Text("MoreLocalization 当前语言:${MoreLocalization.of(context).currentLocalized.name}"),
                    SizedBox(height: 50,),
                    Text("Localizations 当前语言:${Localizations.localeOf(context)}"),
                    SizedBox(height: 50,),
                    Text("Store 当前语言:${store.state.locale.languageCode}"),
                  ],
                )
            ),
          );
        }
    );
  }
}
效果

当前系统的语言改为了中文,所以下面3个文本显示的都是中文的内容
在这里插入图片描述

总结

关键点就是实现 Delegate类Localizations类

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flutter Redux 是一种用于管理 Flutter 应用状态的开源库,它基于 Redux 设计模式。Redux 的核心思想是将应用的状态存储在一个单一的数据源(store),通过修改 store 的状态来更新应用的 UI。Flutter Redux 可以让你轻松地实现这种模式,从而更好地管理应用的状态。 下面是如何使用 Flutter Redux 的简单步骤: 1. 安装 Flutter Redux 包 在你的 Flutter 项目,添加 Flutter Redux 包到你的 `pubspec.yaml` 文件: ``` dependencies: flutter_redux: ^0.8.2 ``` 然后运行 `flutter packages get` 命令来安装依赖包。 2. 创建 Store 创建一个新的文件来表示你的应用状态,并创建一个新的 Store 对象来存储应用的状态。 ```dart import 'package:flutter_redux/flutter_redux.dart'; import 'package:redux/redux.dart'; enum Actions { Increment, } int counterReducer(int state, dynamic action) { if (action == Actions.Increment) { return state + 1; } return state; } final store = Store<int>(counterReducer, initialState: 0); ``` 在上面的示例,我们创建了一个名为 `counterReducer` 的函数来处理应用状态的变化。我们还创建了一个名为 `store` 的全局变量来存储应用状态。 3. 创建 Widget 创建一个新的 Widget 并将 Store 传递给它。 ```dart class CounterWidget extends StatelessWidget { @override Widget build(BuildContext context) { return StoreProvider<int>( store: store, child: MaterialApp( title: 'Counter App', home: CounterPage(), ), ); } } class CounterPage extends StatelessWidget { @override Widget build(BuildContext context) { return StoreConnector<int, int>( converter: (store) => store.state, builder: (context, count) { return Scaffold( appBar: AppBar(title: Text('Counter')), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( '$count', style: Theme.of(context).textTheme.display1, ), RaisedButton( child: Text('Increment'), onPressed: () { store.dispatch(Actions.Increment); }, ), ], ), ), ); }, ); } } ``` 在上面的示例,我们创建了一个名为 `CounterWidget` 的 Widget,并将 `store` 传递给 `StoreProvider`。然后我们创建了一个名为 `CounterPage` 的 Widget,该 Widget 使用 `StoreConnector` 来将 Store 的状态映射到一个 Widget 。我们还在 `RaisedButton` 上注册了一个点击回调函数,该函数将触发一个 Action 来更新 Store 的状态。 4. 运行应用 现在你可以运行你的应用并看到一个简单的计数器应用程序。当你点击按钮时,计数器会增加。这是因为我们在 Store 注册了一个 Reducer 函数来处理该 Action 的状态变化。 这只是 Flutter Redux 的基础用法,你可以在官方文档找到更多的示例和 API 文档。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值