上一次咱们建立了项目,集成了 fish-redux ,安装了插件,并写出第一个页面,此次咱们更详细的了解 fish-redux 。并实现一个简单的列表。效果: 后端
咱们用上一篇讲述的的方式:建立 package 、建立 FishReduxTemplate 来获得新的页面,取名叫 Grid 。 api
把这个页面也添加到app.dart的页面路由中。app.dart修改以下并发
Widget createApp() {
final AbstractRoutes routes = PageRoutes(
pages: <String, Page<Object, dynamic>>{
'entrance_page': EntrancePage(),
'grid_page': GridPage(), //添加这一行
},
);
//省略 ...
}
复制代码
而后编辑这个页面的 view.dart,暂且让它显示一行文字。/grid/view.dart以下app
import 'package:fish_redux/fish_redux.dart';
import 'package:flutter/material.dart';
import 'state.dart';
Widget buildView(GridState state, Dispatch dispatch, ViewService viewService) {
return Scaffold(
appBar: new AppBar(
title: new Text('Grid页面'),
),
body: Text("Grid页面"),
);
}
复制代码
理清思路:为了从 entrance 页面跳转到 grid 页面。咱们须要:ide
咱们打开 /entrance/action.dart 发现由模板建立的代码中为咱们默认定义了一个action,咱们照它的样子添加本身的 action ,取名叫 openGrid 表示打开 grid 页面的事件。修改后的 /entrance/action.dart 以下函数
import 'package:fish_redux/fish_redux.dart';
enum EntranceAction { action, openGrid }//增长openGrid
class EntranceActionCreator {
static Action onAction() {
return const Action(EntranceAction.action);
}
//咱们定义的
static Action onOpenGrid() {
return const Action(EntranceAction.openGrid);
}
}
复制代码
咱们打开 /entrance/view.dart,为 RaisedButton 写点击事件 onPress。在这里dispatch咱们定义的OpenGrid事件。post
dispatch(EntranceActionCreator.onOpenGrid());
复制代码
修改后的 /entrance/view.dart以下 ui
打开 /entrance/effect.dart,让它接收并处理咱们定义的 OpenGrid Action。 /entrance/effect.dart代码以下spa
import 'package:fish_redux/fish_redux.dart';
import 'package:flutter/widgets.dart' hide Action; //注意1
import 'action.dart';
import 'state.dart';
Effect<EntranceState> buildEffect() {
return combineEffects(<Object, Effect<EntranceState>>{
EntranceAction.action: _onAction,
EntranceAction.openGrid: _onOpenGrid, //接收openGrid事件
});
}
void _onAction(Action action, Context<EntranceState> ctx) {
}
//处理openGrid事件
void _onOpenGrid(Action action, Context<EntranceState> ctx) {
Navigator.of(ctx.context).pushNamed('grid_page', arguments: null); //注意2
}
复制代码
这里有两个地方要注意。第一个地方是因为咱们跳转页面引入的 widgets.dart 包含 Action 类,会与 fish-redux 的 Action 冲突并报错,因此在 import 时须要 hide Action ,以后就不在赘述。另外,pushNamed() 方法第一个参数就是咱们在 app.dart 里面定义的页面路由。
而后咱们运行看看效果:点击进入,跳转到了grid页面。
如今咱们来把 grid 页面改形成一个简单的列表。
我新建一个 model.dart 存放个人数据实体类 。我在 GridModel 简单的定义了一个 name 字段 model.dart 以下
而后在 grid 页面的 state.dart 中,建立数据的集合。修改后端 /grid/state.dart以下
import 'package:fish_redux/fish_redux.dart';
import '../model.dart';
class GridState implements Cloneable<GridState> {
List<GridModel> models; // 存放数据
@override
GridState clone() {
return GridState()
..models = models; //clone规则
}
}
GridState initState(Map<String, dynamic> args) {
return GridState();
}
复制代码
接着咱们在页面中经过 gridview 展现咱们的数据,列表的数据就采用 state 中的 models。修改 /grid/view.dart 以下
import 'package:fish_redux/fish_redux.dart';
import 'package:flutter/material.dart';
import 'state.dart';
Widget buildView(GridState state, Dispatch dispatch, ViewService viewService) {
return Scaffold(
appBar: new AppBar(
title: new Text('Grid页面'),
),
body: new GridView.count(
crossAxisCount: 2,//列数
crossAxisSpacing: 20.0,// 左右间隔
mainAxisSpacing: 20.0,// 上下间隔
childAspectRatio: 1 / 1, //宽高比
padding: EdgeInsets.all(20),
children: new List.generate(state.models.length, (index) {//使用state里面的models生成列表
return Center(
child: Card(
color: Colors.lightBlueAccent,
child: InkWell(
splashColor: Colors.blue.withAlpha(100),
onTap: () {
//todo 点击事件
},
child: Container(
width: 200,
height: 200,
child: Center(
child: Text(state.models[index].name),//展现name字段
),
),
),
));
}),
),
);
}
复制代码
数据格式和展现样式都已经完成,接下来咱们来得到数据。
我建立一个 api.dart 用来进行数据请求。
import 'model.dart';
class Api {
factory Api() {
return _get();
}
static Api _instance;
Api._internal() {
//init Api instance
}
static _get() {
if (_instance == null) {
_instance = Api._internal();
}
return _instance;
}
List<GridModel> getGridData() {
return [
GridModel(name: "第一块"),
GridModel(name: "第二块"),
GridModel(name: "第三块"),
GridModel(name: "第四块"),
GridModel(name: "第五块"),
GridModel(name: "第六块"),
GridModel(name: "第七块"),
GridModel(name: "第八块"),
GridModel(name: "第九块"),
GridModel(name: "第十块"),
];
}
}
复制代码
咱们须要在 grid 页面进入时进行数据加载。首先经过 effect 接收 state 初始化的生命周期事件,在 state 初始化的时候,咱们 dispatch 一个加载数据的 action 给 reducer,reducer 接收事件,请求数据并更新 state 。
在 /grid/action.dart 中添加一个 action, 取名 loadData。添加后以下
import 'package:fish_redux/fish_redux.dart';
enum GridAction { action, loadData }
class GridActionCreator {
static Action onAction() {
return const Action(GridAction.action);
}
static Action onLoadData() {
return Action(GridAction.loadData);
}
}
复制代码
而后在 effect 中监听初始化事件,并发送 loadData Action。修改后的 /grid/effect.dart 以下
import 'package:fish_redux/fish_redux.dart';
import 'action.dart';
import 'state.dart';
Effect<GridState> buildEffect() {
return combineEffects(<Object, Effect<GridState>>{
Lifecycle.initState: _init, //页面初始化
GridAction.action: _onAction,
});
}
void _onAction(Action action, Context<GridState> ctx) {
}
void _init(Action action, Context<GridState> ctx) {
ctx.dispatch(GridActionCreator.onLoadData()); //发送事件
}
复制代码
最后在 reducer 中接收 loadData 事件,调用 Api 请求数据, 并更新 state 。修改后的 /grid/reducer.dart以下
import 'package:fish_redux/fish_redux.dart';
import '../api.dart';
import 'action.dart';
import 'state.dart';
Reducer<GridState> buildReducer() {
return asReducer(
<Object, Reducer<GridState>>{
GridAction.action: _onAction,
GridAction.loadData: _onLoadData, //接收loadData Action
},
);
}
GridState _onAction(GridState state, Action action) {
final GridState newState = state.clone();
return newState;
}
//初始化数据
GridState _onLoadData(GridState state, Action action) {
final GridState newState = state.clone()..models = Api().getGridData();//从Api请求数据
return newState;
}
复制代码
运行一下看看效果
🤗若是个人内容对您有帮助,欢迎点赞、评论、转发、收藏。