Flutter之跨組件狀態共享(Provider)
Flutter是Google(全球頂級互聯網科技公司)出品,后臺夠硬,毫無疑問Flutter即將或已經成為跨平臺開發的主流,Flutter野心很大,不僅沖擊著原生開發,而且很有可能會燒到Web前端。作為移動端開發者的你,如果不關注Flutter的話,實在說不過去啦!
Flutter跨組件狀態共享(Provider)應用
一、效果圖
界面初始化狀態
分別點擊兩個按鈕,數據會相應變化
2、Flutter中集Provider
在pubspec.yaml文件中添加Provider,當前版本1.1.0:
provider: ^3.1.0
2、創建用戶實體
商品實體
class Item {
Item(this.price, this.count);
double price; //商品單價
int count; // 商品份數
}
創建CartModel用來管理商品數據
import 'package:flutter/material.dart';
import 'package:ydcflutter_app/common/test/Item.dart';
class CartModel extends ChangeNotifier {
// 用于保存購物車中商品列表
final List<Item> _items = [];
// 購物車中商品的總價
double get totalPrice =>
_items.fold(0, (value, item) => value + item.count * item.price);
// 將 [item] 添加到購物車。這是唯一一種能從外部改變購物車的方法。
void add(Item item) {
_items.add(item);
// 通知監聽器(訂閱者),重新構建InheritedProvider, 更新狀態。
notifyListeners();
}
var name;
CartModel(this.name);
void setName(String name) {
this.name = name;
notifyListeners();
}
String get getName => this.name;
}
我們將要共享的狀態放到一個 CartModel類中,然后讓它繼承自ChangeNotifier,這樣當共享的狀態改變時,我們只需要調用notifyListeners() 來通知訂閱者,然后由訂閱者來重新構建InheritedProvider,達到刷新頁面的目的。
3、使用ChangeNotifierProvider綁定數據
import 'package:flutter/material.dart';
import 'package:ydcflutter_app/common/test/CartModel.dart';
import 'package:ydcflutter_app/common/test/Item.dart';
import 'package:provider/provider.dart';
class TestPage extends StatefulWidget {
@override
State createState() => new _TestPageState();
}
class _TestPageState extends State<TestPage> {
BuildContext mContext;
@override
void initState() {
// TODO: implement initState
super.initState();
}
@override
Widget build(BuildContext context) {
return new Scaffold( body:Center(
child: ChangeNotifierProvider<CartModel>.value(
value: new CartModel("格子襯衫"),
child: Builder(builder: (context) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Builder(builder: (context) {
var cart = Provider.of<CartModel>(context);
return Text("商品名稱: ${cart.name}");
}),
Builder(builder: (context) {
var cart = Provider.of<CartModel>(context);
return Text("總價: ${cart.totalPrice}");
}),
Builder(builder: (context) {
print("RaisedButton build"); //在后面優化部分會用到
return RaisedButton(
child: Text("添加商品"),
onPressed: () {
//給購物車中添加商品,添加后總價會更新
Provider.of<CartModel>(context).add(Item(10.0, 1));
},
);
}),
Builder(builder: (context) {
print("RaisedButton build"); //在后面優化部分會用到
return RaisedButton(
child: Text("修改商品名稱"),
onPressed: () {
//使用Provider修改商品名稱
Provider.of<CartModel>(context).setName("修改為無用牌毛巾");
},
);
}),
],
);
}),
),
));
}
Widget dividerWidget = new Container(
//margin: const EdgeInsets.only( left: 10.0,right: 10.0),
child: new Padding(
padding: const EdgeInsets.only(left: 0.0, right: 0.0),
child:
new Divider(height: 1.0, indent: 0.0, color: Color(0xFFe5e5e5))
)
);
@override
void dispose() {
super.dispose();
}
}
ChangeNotifierProvider調用value()方法,里面傳出notifier(CartModel)和child,并初始化了默認數據。
4、使用Provider獲取數據
Builder(builder: (context) {
var cart = Provider.of<CartModel>(context);
return Text("商品名稱: ${cart.name}");
}),
5、使用Provider更新數據
Builder(builder: (context) {
print("RaisedButton build"); //在后面優化部分會用到
return RaisedButton(
child: Text("添加商品"),
onPressed: () {
//給購物車中添加商品,添加后總價會更新
Provider.of<CartModel>(context).add(Item(10.0, 1));
},
);
}),
Builder(builder: (context) {
print("RaisedButton build"); //在后面優化部分會用到
return RaisedButton(
child: Text("修改商品名稱"),
onPressed: () {
//使用Provider修改商品名稱
Provider.of<CartModel>(context).setName("修改為無用牌毛巾");
},
);
}),
通過調用 ChangeNotifier.notifyListeners 對 ChangeNotifier(CartModel) 進行監聽,將其公開給它的子 Widget 并重建依賴項,從而刷新我們的UI。
以上已經完成單個頁面狀態的管理,如果你想實現跨組件,跨路由狀態共享。你只要把ChangeNotifierProvider放在整個應用的Widget樹的根上即可。
各個頁面中直接這樣使用即可。
Flutter商城項目實戰:https://github.com/dechengyang/ydc_flutter_app
如果對你有幫助,隨意賞我奶粉錢吧,多謝!
微信:
支付寶:
智能推薦
React多組件狀態共享之Redux
什么是Redux 2013年 Facebook 提出了 Flux 架構的思想,引發了很多的實現。2015年,Redux 出 現,將 Flux 與函數式編程結合一起,很短時間內就成為了最熱門的前端架構。 Redux的官方解釋是:Redux is a predictable state container for JavaScript apps. 意思 就是Redux是js應用的一種可預測的狀態容器。...
輕松flutter之 組件狀態管理
管理狀態的最常見的方法: 方法 描述 自身狀態管理 Widget管理自己的狀態。 父組件管理子組件狀態 父Widget管理子Widget狀態。 混合管理 混合管理(父Widget和子Widget都管理狀態)。 全局狀態管理 使用第三方庫進行全局狀態管理 關于狀態管理原則: 如果狀態是用戶數據,如復選框的選中狀態、滑塊的位置,則該狀態最好由父Widget管理。 如果狀態是有關界面外觀效果的,例如顏色...
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...
電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!
Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...
猜你喜歡
requests實現全自動PPT模板
http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...
Linux C系統編程-線程互斥鎖(四)
互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...
統計學習方法 - 樸素貝葉斯
引入問題:一機器在良好狀態生產合格產品幾率是 90%,在故障狀態生產合格產品幾率是 30%,機器良好的概率是 75%。若一日第一件產品是合格品,那么此日機器良好的概率是多少。 貝葉斯模型 生成模型與判別模型 判別模型,即要判斷這個東西到底是哪一類,也就是要求y,那就用給定的x去預測。 生成模型,是要生成一個模型,那就是誰根據什么生成了模型,誰就是類別y,根據的內容就是x 以上述例子,判斷一個生產出...
styled-components —— React 中的 CSS 最佳實踐
https://zhuanlan.zhihu.com/p/29344146 Styled-components 是目前 React 樣式方案中最受關注的一種,它既具備了 css-in-js 的模塊化與參數化優點,又完全使用CSS的書寫習慣,不會引起額外的學習成本。本文是 styled-components 作者之一 Max Stoiber 所寫,首先總結了前端組件化樣式中的最佳實踐原則,然后在此基...