请考虑以下代码:
StreamBuilder<QuerySnapshot> _createDataStream(){
return StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection("data").limit.(_myLimit).snapshots(),
builder: (context, snapshot){
return Text(_myLimit.toString);
}
);
}
我希望_myLimit
变量更改时StreamBuilder刷新。可以这样做:
void _incrementLimit(){
setState(() =>_myLimit++);
}
我的问题是,除了setState((){});
之外,还有没有其他更快的方法。因为当build()
变量更改时,我不想重新调用整个_myLimit
方法。
[我想出了另一种方法,但是我觉得有更好的解决方案,因为我认为我没有使用.periodic
功能,而且我得到了嵌套的Stream,所以我不确定这是多么平常:
Stream<int> myStream = Stream.periodic(Duration(), (_) => _myLimit);
...
@override
Widget build(BuildContext context){
...
return StreamBuilder<int>(
stream: myStream,
builder: (context, snapshot){
return _createDataStream;
},
),
...
}
用broadcast
声明一个StreamController,然后为该StreamController的Stream设置一个友好的名称,然后每次您要重建包装的窗口小部件时,只需将sink
的StreamController
属性设置为add
一个新值这将触发StreamBuilder
。
final StreamController<UserModel> _currentUserStreamCtrl = StreamController<UserModel>.broadcast();
Stream<UserModel> get onCurrentUserChanged => _currentUserStreamCtrl.stream;
void updateCurrentUserUI() => _currentUserStreamCtrl.sink.add(_currentUser);
StreamBuilder<UserModel>(
stream: blocs.auth.onCurrentUserChanged,
builder: (BuildContext context, AsyncSnapshot<UserModel> snapshot) {
if (snapshot.data != null) {
print('build signed screen');
return blocs.pageView.pagesView; //pageView containing signed
}
print('build login screen');
return LoginPage();
},
)
通过这种方式,您可以使用无状态小组件并仅刷新单个子小部件(例如,具有不同颜色的图标),而无需使用setState(可以重建整个页面)。
为了提高性能,流是最好的方法。
编辑:我使用的是BLoC体系结构方法,因此最好在homePageBloc.dart(具有所有业务逻辑的普通控制器类)中声明变量,并在homePage.dart(具有可扩展Stateless的类)中创建StreamBuilder / Stateful小部件,并负责UI)。