適用于多次數(shù)據(jù)變化
既然有了FutureBuilder 一次性的數(shù)據(jù)變化更新視圖,那就有多次,那就來看看StreamBuilder吧
import 'dart:async';
import 'package:flutter/material.dart';
class StatePage extends StatefulWidget {
@override
StatePageState createState() => new StatePageState();
}
class StatePageState extends State<StatePage> {
StreamController streamController = new StreamController();
int index = 0;
@override
Widget build(BuildContext context) {
print('test StatePageState build');
return Scaffold(
appBar: AppBar(
title: Text('statPage', style: TextStyle(fontSize: 16)),
centerTitle: true,
),
body: Align(
child: Column(
children: <Widget>[
StreamBuilder(
stream: streamController.stream,
initialData: index,
builder: (context, snapshot) {
print('test FutureBuilder builder');
return Text("this number:${snapshot.data}");
},
),
RaisedButton(
child: Text('add $index'),
onPressed: countChange,
),
RaisedButton(
child: Text('add2'),
onPressed: add,
),
],
),
));
}
void countChange() {
streamController.add(++index);
}
void add() {
setState(() {
index += 10;
});
}
@override
void dispose() {
streamController.close();
super.dispose();
}
}
StreamBuilder繼承了StreamBuilderBase解幼,StreamBuilderBase又繼承了StatefulWidget,所以StreamBuilder中的builder中的視圖丟給了一個StatefulWidget崎脉,在這個StatefulWidget中接收外面?zhèn)鬟M來的一個Stream,用于監(jiān)聽數(shù)據(jù)變化更新,可以看_StreamBuilderBaseState中_subscribe代碼
void _subscribe() {
if (widget.stream != null) {
_subscription = widget.stream.listen((T data) {
setState(() {
_summary = widget.afterData(_summary, data);
});
}, onError: (Object error) {
setState(() {
_summary = widget.afterError(_summary, error);
});
}, onDone: () {
setState(() {
_summary = widget.afterDone(_summary);
});
});
_summary = widget.afterConnected(_summary);
}
}
當(dāng)?shù)谝粋€RaisedButton 點擊執(zhí)行countChange更新stream的值后伯顶,_StreamBuilderBaseState中_subscribe方法中widget.stream.listen 會監(jiān)聽到數(shù)據(jù)變化囚灼,執(zhí)行setState更新當(dāng)前StatefulWidget,也就是會調(diào)用我們定義的StreamBuilder中builder方法
但是當(dāng)我們自己setState的時候祭衩,StreamBuilder中的builder方法同樣會被執(zhí)行啦撮,因為這個小部件在我們自己build中,但是這個時候取的snapshot.data并變化汪厨,因為snapshot.data取的是stream中的值,這個stream的值并沒有發(fā)生改變