写点什么

Flutter 完整开发实战详解 (四、 Redux、主题,某大厂开发者对于 Android 多线程的总结

用户头像
Android架构
关注
发布于: 51 分钟前

]);


///定义处理 Action 行为的方法,返回新的 StateThemeData _refresh(ThemeData themeData, action) {themeData = action.themeData;return themeData;}


///定义一个 Action 类///将该 Action 在 Reducer 中与处理该 Action 的方法绑定 class RefreshThemeDataAction {


final ThemeData themeData;


RefreshThemeDataAction(this.themeData);}


OK,现在我们可以愉悦的创建 Store 了。如下代码所示,在创建 Store 的同时,我们通过 initialState 对 GSYState 进行了初始化,然后通过 StoreProvider 加载了 Store 并且包裹了 MaterialApp至此我们完成了 Redux 中的初始化构建。


void main() {runApp(new FlutterReduxApp());}


class FlutterReduxApp extends StatelessWidget {/// 创建 Store,引用 GSYState 中的 appReducer 创建 Reducer/// initialState 初始化 Statefinal store = new Store<GSYState>(appReducer,initialState: new GSYState(userInfo: User.empty(),themeData: new ThemeData(primarySwatch: GSYColors.primarySwatch,),locale: Locale('zh', 'CH')),);


FlutterReduxApp({Key key}) : super(key: key);


@overrideWidget build(BuildContext context) {/// 通过 StoreProvider 应用 storereturn new StoreProvider(store: store,child: new MaterialApp(),);}}


And then,接下来就是使用了。如下代码所示,通过在 build 中使用 StoreConnector ,通过 converter 转化 store.state 的数据,最后通过 builder 返回实际需要渲染的控件,这样就完成了数据和控件的绑定。当然,你也可以使用StoreBuilder


class DemoUseStorePage extends StatelessWidget {@overrideWidget build(BuildContext context) {///通过 StoreConnector 关联 GSYState 中的 Userreturn new StoreConnector<GSYState, User>(///通过 converter 将 GSYState 中的 userInfo 返回 converter: (store) => store.state.userInfo,///在 userInfo 中返回实际渲染的控件 builder: (context, userInfo) {return new Text(userInfo.name,);},);}}


最后,当你需要触发更新的时候,只需要如下代码即可。


StoreProvider.of(context).dispatch(new UpdateUserAction(newUserInfo));


So,或者简单的业务逻辑下,Redux 并没有什么优势,甚至显得繁琐。但是一旦框架搭起来,在复杂的业务逻辑下就会显示格外愉悦了。

二、主题

Flutter 中官方默认就支持主题设置,MaterialApp 提供了 theme 参数设置主题,之后可以通过 Theme.of(context) 获取到当前的 ThemeData 用于设置控件的颜色字体等。


ThemeData 的创建提供很多参数,这里主要说 primarySwatch 参数。 primarySwatch 是一个 MaterialColor 对象,内部由 10 种不同深浅的颜色组成,用来做主题色调再合适不过。


如下图和代码所示,Flutter 默认提供了很多主题色,同时我们也可以通过 MaterialColor 实现自定义的主题色。



MaterialColor primarySwatch = const MaterialColor(primaryValue,const <int, Color>{50: const Color(primaryLightValue),100: const Color(primaryLightValue),200: const Color(primaryLightValue),300: const Color(primaryLightValue),400: const Color(primaryLightValue),500: const Color(primaryValue),600: const Color(primaryDarkValue),700: const Color(primaryDarkValue),800: const Color(primaryDarkValue),900: const Color(primaryDarkValue),},);


那如何实现实时的主题切换呢?当然是通过 Redux 啦!


前面我们已经在 GSYState 中创建了 themeData ,此时将它设置给 MaterialApptheme 参数,之后我们通过 dispatch 改变 themeData 即可实现主题切换。


注意,因为你的 MaterialApp 也是一个 StatefulWidget ,如下代码所示,还需要利用 StoreBuilder 包裹起来,之后我们就可以通过 dispatch 修改主题,通过 Theme.of(context).primaryColor 获取主题色啦。


@overrideWidget build(BuildContext context) {/// 通过 StoreProvider 应用 storereturn new StoreProvider(store: store,child: new StoreBuilder<GSYState>(builder: (context, store) {return new MaterialApp(theme: store.state.themeData);}),);}


····


ThemeData themeData = new ThemeData(primarySwatch: colors


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


[index]);store.dispatch(new RefreshThemeDataAction(themeData));


三、国际化

Flutter 的国际化按照官网文件 [internationalization](


) 看起来稍微有些复杂,也没有提及实时切换,所以这里介绍下快速的实现。当然,少不了 Redux !



如上图所示大致流程,同样是通过默认 MaterialApp 设置,自定义的多语言需要实现的是: LocalizationsDelegateLocalizations。最终流程会通过 Localizations 使用 Locale 加载这个 delegate。所以我们要做的是:


  • 实现 LocalizationsDelegate

  • 实现 Localizations

  • 通过 StoreLocale 切换语言。


如下代码所示,创建自定义 delegate 需要继承 LocalizationsDelegate 对象,其中主要实现 load 方法。我们可以是通过方法的 locale 参数,判断需要加载的语言,然后返回我们自定义好多语言实现类 GSYLocalizations ,最后通过静态 delegate 对外提供 LocalizationsDelegate


/**


  • 多语言代理

  • Created by guoshuyu

  • Date: 2018-08-15*/class GSYLocalizationsDelegate extends LocalizationsDelegate<GSYLocalizations> {


GSYLocalizationsDelegate();


@overridebool isSupported(Locale locale) {///支持中文和英语 return ['en', 'zh'].contains(locale.languageCode);}


///根据 locale,创建一个对象用于提供当前 locale 下的文本显示 @overrideFuture<GSYLocalizations> load(Locale locale) {return new SynchronousFuture<GSYLocalizations>(new GSYLocalizations(locale));}


@overridebool shouldReload(LocalizationsDelegate<GSYLocalizations> old) {return false;}


///全局静态的代理 static GSYLocalizationsDelegate delegate = new GSYLocalizationsDelegate();}


上面提到的 GSYLocalizations 其实是一个自定义对象,如下代码所示,它会根据创建时的 Locale ,通过 locale.languageCode 判断返回对应的语言实体:GSYStringBase 的实现类


因为 GSYLocalizations 对象最后会通过Localizations 加载,所以 Locale 也是在那时,通过 delegate 赋予。同时在该 context 下,可以通过Localizations.of 获取 GSYLocalizations,比如: GSYLocalizations.of(context).currentLocalized.app_name


///自定义多语言实现 class GSYLocalizations {final Locale locale;


GSYLocalizations(this.locale);


///根据不同 locale.languageCode 加载不同语言对应///GSYStringEn 和 GSYStringZh 都继承了 GSYStringBasestatic Map<String, GSYStringBase> _localizedValues = {'en': new GSYStringEn(),'zh': new GSYStringZh(),};


GSYStringBase get currentLocalized {return _localizedValues[locale.languageCode];}


///通过 Localizations 加载当前的 GSYLocalizations///获取对应的 GSYStringBasestatic GSYLocalizations of(BuildContext context) {return Localizations.of(context, GSYLocalizations);}}


///语言实体基类 abstract class GSYStringBase {String app_name;}


///语言实体实现类 class GSYStringEn extends GSYStringBase {@overrideString app_name = "GSYGithubAppFlutter";}


///使用 GSYLocalizations.of(context).currentLocalized.app_name


说完了 delegate , 接下来就是 Localizations 了。在上面的流程图中可以看到, Localizations 提供一个 override 方法构建 Localizations ,这个方法中可以设置 locale,而我们需要的正是实时的动态切换语言显示


如下代码,我们创建一个 GSYLocalizations 的 Widget,通过 StoreBuilder 绑定 Store,然后通过 Localizations.override 包裹我们需要构建的页面,将 Store 中的 locale 和 Localizations 的 locale 绑定起来。


class GSYLocalizations extends StatefulWidget {final Widget child;


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


@overrideState<GSYLocalizations> createState() {return new _GSYLocalizations();}}class _GSYLocalizations extends State<GSYLocalizations> {


@overrideWidget build(BuildContext context) {return new StoreBuilder<GSYState>(builder: (context, store) {///通过 StoreBuilder 和 Localizations 实现实时多语言切换

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Flutter完整开发实战详解(四、 Redux、主题,某大厂开发者对于Android多线程的总结