《Flutter学习笔记》redux状态管理 实现换肤

参考文档 https://guoshuyu.cn/home/wx/Flutter-4.html

Redux

由于之前使用react框架,所以对于redux的一些概念会相对熟悉。对于不了解的朋友可以阅读以下文档进行入门redux:

  • Redux 中文文档
  • 精简版redux-tutorial

redux主要涉及以下概念:

  • Store: 用来保存数据的地方,整个项目只能有一个store,Store中定义了一个非常重要的方法 dispatch(action) 用来发送action ,触发事件的发生.
  • State: store对象包含的所有数据.
  • Action: state的变化会导致view的变化,用户通过接触view ,使用action发出通知,来更改action。store.dispatch()是view发出action的唯一方法.
  • Reducer: 将传入的state处理成新的state,是一个纯函数.

Flutter + Redux

在flutterd当中使用redux,需要引入两个库

import 'package:redux/redux.dart';
import 'package:flutter_redux/flutter_redux.dart';

首先需要创建一个State对象 AppState 类,用于存放我们需要的共享数据,例如本项目中的皮肤颜色themeData

class AppState {
  ThemeData themeData;
  AppState({this.themeData});
}

接着需要定义Reducer方法 appReducer ,将AppState内的参数和对应的 action 绑定起来,返回新的AppState。

AppState appReducer(AppState state, action) {
  return AppState(
    themeData: themeDataDeducer(state.themeData, action),
  );
}

通过 flutter_redux 的 combineReducersTypedReducer,将 UpdateThemeData 类 和 _updateThemeData 方法绑定起来,最终会返回一个 ThemeData 实例。也就是说:用户每次发出一个 UpdateThemeData ,最终都会触发 _updateThemeData 方法,然后更新 AppState 中的 themeData

final themeDataDeducer = combineReducers([
  TypedReducer(_updateThemeData),
]);

ThemeData _updateThemeData(ThemeData themeData, action) {
  themeData = action.themeData;
  return themeData;
}

class UpdateThemeDataAction {
  final ThemeData themeData;
  UpdateThemeDataAction(this.themeData);
}

接下来可以开始编写我们的页面,对redux进行初始化构建,使用 StoreProvider 应用 store,因为 MaterialApp 也是一个 StatefulWidget ,如下代码所示,还需要利用 StoreBuilder 包裹起来,通过store.state.themeData来获取主题色。

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

class ReduxApp extends StatelessWidget {
  final store = new Store(
    appReducer,
    initialState: new AppState( // 进行主题颜色初始化
        themeData: ThemeData(
      primaryColor: Colors.black,
    )),
  );
  ReduxApp({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
  /// 通过 StoreProvider 应用 store
    return StoreProvider(
        store: store,
        child: StoreBuilder(
          builder: (context, store) {
            return MaterialApp(
              theme: store.state.themeData,
              home: Newpage(),
            );
          },
        ));
  }
}

接下来是 Newpage 页面,用来控制颜色的改变,包含三个按钮,蓝色、红色、绿色,使用 dispatch 来触发颜色的改变,这里需要使用 StoreProvider.of(context)来传入上下文

class Newpage extends StatelessWidget {
  TextStyle fontColor = TextStyle(color: Colors.white);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('皮肤')),
      body: Center(
        child: Column(
          children: [
            FlatButton(
                child: Text('蓝色', style: fontColor),
                onPressed: () {
                  ThemeData themeData =
                      new ThemeData(primarySwatch: Colors.blue);
                  StoreProvider.of(context)
                      .dispatch(new UpdateThemeDataAction(themeData));
                },
                color: Colors.blue),
            FlatButton(
                child: Text('红色', style: fontColor),
                onPressed: () {
                  ThemeData themeData =
                      new ThemeData(primarySwatch: Colors.red);
                  StoreProvider.of(context)
                      .dispatch(new UpdateThemeDataAction(themeData));
                },
                color: Colors.red),
            FlatButton(
                child: Text('绿色', style: fontColor),
                onPressed: () {
                  ThemeData themeData =
                      new ThemeData(primarySwatch: Colors.green);
                  StoreProvider.of(context)
                      .dispatch(new UpdateThemeDataAction(themeData));
                },
                color: Colors.green),
          ],
        ),
      ),
    );
  }
}

最后的实现效果如下所示

《Flutter学习笔记》redux状态管理 实现换肤_第1张图片

该教程是我接触flutter的第一周写的,今天刚好在看redux的教程,因此写了这样一个小demo,可能有许多地方需要改进,希望各位大佬还请多多指点~

你可能感兴趣的:(flutter,flutter)