Redux應(yīng)用
概述
Flutter 是 Google 開(kāi)源的 跨平臺(tái)開(kāi)發(fā)工具,我們可以在anroid,iOS上完成功能開(kāi)發(fā),避免兩撥人力成本。
Redux對(duì)于JavaScript應(yīng)用而言是一個(gè)可預(yù)測(cè)狀態(tài)的容器。換言之,它是一個(gè)應(yīng)用數(shù)據(jù)流框架,而不是傳統(tǒng)的像underscore.js或者AngularJs那樣的庫(kù)或者框架。后來(lái)在Rn和Flutter上都開(kāi)發(fā)了,今天給大家分享一下在Flutter中使用Redux。
一、集成Redux
在項(xiàng)目的pubspec.yaml的dependencies中添加:
dependencies:
...
redux: 4.0.0
flutter_redux: ^0.6.0
二、安裝
當(dāng)我們編輯了pubspec.yaml文件,AndroidStudio的編輯區(qū)域右上角會(huì)顯示put get樣式,直接點(diǎn)擊就可安裝。
你也可以在項(xiàng)目的更目錄執(zhí)行:flutter pub get
pub 官網(wǎng)有詳細(xì)介紹安裝步驟:https://pub.dev/packages/scoped_model#-installing-tab-
三、Redux使用
定義model
定義State
定義Action,操作類(lèi)型,比如添加書(shū)、刪除書(shū)等不同類(lèi)型的標(biāo)識(shí)。
定義Reducer(定義了應(yīng)用如何響應(yīng)Redux發(fā)出Action,即發(fā)出的Action由誰(shuí)處理)
創(chuàng)建Store,負(fù)責(zé)綁定Reducer和默認(rèn)數(shù)據(jù)。
使用Redux在Flutter中提供的Widget創(chuàng)建視圖,并和Store綁定。
發(fā)送通過(guò)Store的dispatch發(fā)送Action。
我們通過(guò)一個(gè)添加書(shū)籍列表來(lái)完成Redux的使用,運(yùn)行效果圖:

1、定義model,我們創(chuàng)建一個(gè)book.dart,代碼如下:
/// 定義book 類(lèi)型
class Book {
String name;
int id;
Book({this.name, this.id});
}
2、定義state,創(chuàng)建一個(gè)book_state.dart文件,代碼如下:
/// 持有一個(gè)類(lèi)型是book的list對(duì)象
class BookListState{
List books; BookListState({this.books});}
3、定義Action,分別定義一個(gè)添加和刪除的Action。并定義刪除書(shū)和添加書(shū)的邏輯處理方法,創(chuàng)建book_action.dart類(lèi),代碼如下:
import 'package:booklist/book/bean/book.dart';
/// 添加book的Action
class AddBootAction {
Book book;
AddBootAction({this.book});
}
/// 刪除book的Action
class DeleteBootAction {
DeleteBootAction();
}
/// 添加書(shū)籍的方法
/// 注意這里的返回值一定是和我們?cè)贐ookState中定義的狀態(tài)類(lèi)型一樣。
/// 方法參數(shù) books,這個(gè)參數(shù)就是我們?cè)赟tate定義的變量books,Redux發(fā)送消息時(shí),攜帶過(guò)來(lái)。
/// action就是對(duì)應(yīng)的我們上面定義的AddBootAction,二者如何管理,我們?cè)诘谒牟街写_認(rèn)
List addBook(List books, action) {
// 將書(shū)籍添加到列表中。
books.add(action.book);
return books;
}
///刪除書(shū)籍的方法,這里的返回類(lèi)型和形參和上面的一樣。
List deleteBook(List books, action) {
books.removeLast();
return books;
}
4、定義Reducer,將Action和操作方法綁定,創(chuàng)建一個(gè)book_reducer.dart,代碼如下:
import 'package:redux/redux.dart';
import 'package:booklist/book/bean/book.dart';
import 'package:booklist/book/book_action/book_action.dart';
/// 通過(guò)Redux提供的combineReducers方法,將Action和操作方法綁定
/**
* 1、combineReducers是Redux提供創(chuàng)建Reducer的方法。
* 2、combineReducers泛型一定要是我們?cè)赟tate中定義的類(lèi)型。
* 3、TypedReducer是Redux提供的默認(rèn)Reducer響應(yīng)
* 4、TypedReducer的第一個(gè)泛型必須是State中定義的類(lèi)型。
* 5、TypedReducer的第一個(gè)泛型即是我們定義的Action類(lèi)型。
* 6、TypedReducer的形參就是我們?cè)赽ook_action.dart中的定義的具體操作方法。
* 7、dart語(yǔ)音中可以把方法當(dāng)作參數(shù)
* 8、這樣就把Action和方法操作綁定了。有點(diǎn)類(lèi)似EventBus哦
*/
final BookReducer = combineReducers>([
TypedReducer, AddBootAction>(_addBook),
TypedReducer, DeleteBootAction>(_deleteBook),]
);
5、創(chuàng)建Store,將Redux和綁定到Store中,Store一般定義在Widget中,同時(shí)也包含了發(fā)送Action,所以我們創(chuàng)建book_list_widget.dart(包含了5,6,7)
import 'package:booklist/book/bean/book.dart';
import 'package:booklist/book/book_action/book_action.dart';
import 'package:booklist/book/state/book_state.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:redux/redux.dart';
/// 定義有狀態(tài)的widget
class BookListWidget extends StatefulWidget {
@override
State createState() => BookListState();
}
/// flutter狀態(tài)
class BookListState extends State {
// 定義Redux store,包含了Reducer 第五步
final store = new Store(
// 在book_state.dart中定義
bookReducer,
// 設(shè)置一個(gè)默認(rèn)值
initialState: BookList(books: [
Book(name: "java 1", id: 1), ]), );
@override Widget build(BuildContext context) {
// 使用Redux提供的StoreProvider作為root Widget
// 很重要:第六步
return StoreProvider(
store: store,
child: MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Redux使用"),
backgroundColor: Colors.blue[300], ),
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
children: [
RaisedButton(
color: Colors.red[300],
child: Text("添加書(shū)籍"),
onPressed: () {
// 很重要,第七步,通過(guò)store的dispatch 發(fā)送AddbookAction
store.dispatch(AddBookAction(book:
Book(name:"java ${store.state.books.length + 1}",
id: store.state.books.length+1)
));},),
RaisedButton(
color: Colors.red[300],
child: Text("刪除最后一本書(shū)"),
onPressed: () {
// 很重要,第七步,通過(guò)store的dispatch 發(fā)送DeletebookAction
store.dispatch(DeleteBookAction());},),],),
Expanded(
// 很重要,第六步
child: StoreConnector(
converter: (store) => store.state,
builder: (BuildContext context, data) {
return Container(
height: 200,
child: ListView.builder(
itemCount:
data.books.length ,
itemBuilder: (BuildContext context, position) {
return Padding(
padding: EdgeInsets.all(10.0),
child: Row(
children: [
Text(getName(data, position)),
],
),
);
}),); },), )],),),),); }
String getName(BookList bookList, int position) {
return bookList.books[position].name; }
}
四、結(jié)束語(yǔ)
Redux的思路和使用方法同Eventbus類(lèi)似,只是他兩解決的問(wèn)題領(lǐng)域不同步,EventBus重點(diǎn)是解決跨線(xiàn)程通信,Redux重點(diǎn)是解決狀態(tài)更新后,如何刷新UI,加入沒(méi)有Redux,如果我們的頁(yè)面有很多狀態(tài),每個(gè)都需要調(diào)用setState去更新,你想象也行代碼復(fù)雜度得多大
思考:Redux的使用有些模塊類(lèi)型的,是不是有辦法通過(guò)類(lèi)型java apt的方式自動(dòng)生成呢?