谨以此博客纪录一波Fish Redux的用法,怕太久了会忘记!当然了,后续可能还会更深入研究一波,到时候再来更新吧
Fish Redux项目地址
github: https://github.com/alibaba/fish-redux
pub.dev: https://pub.dev/packages/fish_redux
其实学习flutter不要只盯着github,pub dev上的资源可能更多一些
如果是团队开发flutter项目,可能每个人的风格都不太一样,导致写出来的代码千奇百怪的,fish redux就是定义了一种规范,让大家统一风格,当然了也没谁说这就是最好的,你要喜欢用mvp也可以
如果是使用idea开发,建议安装Fish Redux插件,不然一次写好几个类实在是麻烦
鼠标右键包名,选择FishReduxTemplate就可以创建了
使用插件创建的一个模板(当然了,还可以选择adapter,component等等,这里只演示最基础的使用)
先来一张最终效果图,本例主要使用Fish Redux框架来实现“页面跳转”和“刷新页面”两个功能
1.action.dart
import 'package:fish_redux/fish_redux.dart';
///使用枚举定义相应的type
enum TestAction { jumpDetail, changeText }
///定义一系列action
class TestActionCreator {
///跳转动作
static Action onJumpDetail() {
return const Action(TestAction.jumpDetail);
}
///改变Text widget上的值
static Action onChangeText(final String randomText){
return Action(TestAction.changeText, payload: randomText);
}
}
2.state.dart
state文件可以理解为一个实现了cloneable的Bean,通过克隆的方式改变state中的值从而改变页面数据显示
import 'package:fish_redux/fish_redux.dart';
/// State为定义Dart本地数据封装类,其要实现Cloneable接口,当中数据改变通过浅复制方式,
/// 默认插件会实现initState方法
class TestState implements Cloneable<TestState> {
String title;
String subTitle;
String randomText;
TestState({this.title, this.subTitle, this.randomText});
@override
TestState clone() {
return TestState()
..randomText = randomText
..title = title
..subTitle = subTitle;
}
}
TestState initState(Map<String, dynamic> args) {
return TestState();
}
3.view.dart
import 'dart:math';
import 'package:fish_redux/fish_redux.dart';
import 'package:flutter/material.dart';
import 'action.dart';
import 'state.dart';
///组件展示
///TestState 这其实是一个泛型
///Dispatch用于分发一个动作,也就是Action
///ViewService可以调用创建Adapter或是Component
Widget buildView(TestState state, Dispatch dispatch, ViewService viewService) {
return MaterialApp(
title: 'Redux Demo',
theme: ThemeData(primaryColor: Colors.blue),
home: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
//点击跳转到另一个页面
FlatButton(
onPressed: () {
dispatch(TestActionCreator.onJumpDetail());
},
child: Text(
"Redux",
style: TextStyle(fontSize: 30, color: Colors.white),
)),
//点击改变Text的值
FlatButton(
onPressed: () {
var nextInt = Random().nextInt(60000);
dispatch(
TestActionCreator.onChangeText('Random Text: $nextInt'));
},
child: Text(
"Click to Change",
style: TextStyle(fontSize: 30, color: Colors.white),
)),
Text(
state.randomText ?? 'Random Text',
style: TextStyle(fontSize: 15, color: Colors.white),
)
],
),
),
);
}
4.effect.dart
import 'package:fish_redux/fish_redux.dart';
import 'package:flutter/material.dart';
import '../check_index.dart';
import 'action.dart';
import 'state.dart';
///Effect 常用于定义 网络数据请求,或是界面点击事件等非数据操作
Effect<TestState> buildEffect() {
return combineEffects(<Object, Effect<TestState>>{
TestAction.jumpDetail: _onJumpDetail,
});
}
void _onJumpDetail(Action action, Context<TestState> ctx) {
Navigator.push(ctx.context, MaterialPageRoute(builder: (buildContext) {
return CheckIndexPage();
}));
}
5.reducer.dart
import 'package:fish_redux/fish_redux.dart';
import 'action.dart';
import 'state.dart';
///Reducer常用语操作数据行为,通过拿到Action payload中数据来对数据通过浅复制方式改变数据
Reducer<TestState> buildReducer() {
return asReducer(
<Object, Reducer<TestState>>{
TestAction.jumpDetail: _onJumpDetail,
TestAction.changeText: _onChangeAction,
},
);
}
TestState _onJumpDetail(TestState state, Action action) {
final TestState newState = state.clone();
return newState;
}
TestState _onChangeAction(TestState state, Action action) {
final String randomText = action.payload;
final TestState newState = state.clone();
//改变state的值
if (randomText != null) {
newState.randomText = randomText;
}
return newState;
}
注:effect中定义的方法应该是“非数据操作”类型的,譬如网络请求,页面跳转等,如果是要改变state中的值请一定在reducer中定义相应的方法
6.page.dart
这个文件主要是起到一个整合的作用
import 'package:fish_redux/fish_redux.dart';
import 'effect.dart';
import 'reducer.dart';
import 'state.dart';
import 'view.dart';
class TestPage extends Page<TestState, Map<String, dynamic>> {
TestPage()
: super(
initState: initState,
effect: buildEffect(),
reducer: buildReducer(),
view: buildView,
dependencies: Dependencies<TestState>(
adapter: null,
slots: <String, Dependent<TestState>>{
}),
middleware: <Middleware<TestState>>[
],);
}
最后就是在main.dart中调用 TestPage().buildPage(null) 就可以了!
如果是很简单的页面不建议使用fish redux,要写的类实在是有点多。不过对于复杂的业务场景用起来还是很有益处的,业务逻辑清晰了不少