如何使用StreamBuilder执行不同值的网络请求



我使用FutureBuilder小部件根据未来counter的值渲染Text,当我单击浮动动作按钮时,我再次用不同的值调用未来。但是我需要做一个setState后,我点击按钮,以刷新UI,这将是很好的几个小部件在屏幕上,但调用setState将重建其他小部件太。


class _MyHomePageState extends State<MyHomePage> {
Future counter;
@override
void initState() {
super.initState();
counter = counterFuture(4);
}
//This would be a network request with a specific value
Future<int> counterFuture(int i) async {
return await Future.value(i);
}
_changeCounter(int i) {
setState(() {
counter = counterFuture(i);
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FutureBuilder<int>(
future: counter,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data.toString());
}
return Text('loading');
},
),
...other widgets
],
),
),
floatingActionButton: FloatingActionButton(
//tap button to request with a different value
onPressed: () => _changeCounter(9),
),
);
}
}

我的问题是我如何使用流和StreamBuilder来渲染和更新Text小部件来实现这一点?

使用StreamController可以很容易地做到这一点。查看下面的代码片段:

class _MyHomePageState extends State<MyHomePage> {
int counter;
StreamController controller = StreamController<int>();
@override
void initState() {
initialize();
super.initState();
}
initialize() async {
counter = await counterFuture(4);
controller.add(counter);
}
@override
void dispose() {
controller.close();
super.dispose();
}
//This would be a network request with a specific value
Future<int> counterFuture(int i) async {
return await Future.value(i);
}
_changeCounter(int i) async {
counter = await counterFuture(i);
controller.add(counter);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
StreamBuilder<int>(
stream: controller.stream,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(snapshot.data.toString());
}
return Text('loading');
},
),
],
),
),
floatingActionButton: FloatingActionButton(
//tap button to request with a different value
onPressed: () => _changeCounter(9)),
),
);
}
}

最新更新