上一次咱們建立了項目,集成了 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 用來進行數據請求。
我建立一個單例 Api ,把它做爲全局的數據來源。而後完成一個得到 GridModel 數據的函數來給咱們 grid 頁面提供數據。 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;
}
複製代碼
運行一下看看效果
🤗若是個人內容對您有幫助,歡迎點贊、評論、轉發、收藏。