面试题答案
一键面试- 创建Stream:
- 可以使用
Stream.periodic
来创建一个按固定时间间隔生成事件的流。在这个场景中,为了获取实时时间,我们可以每秒生成一个新事件。
Stream<DateTime> timeStream = Stream.periodic(const Duration(seconds: 1), (count) => DateTime.now());
- 可以使用
- 监听Stream:
- 在Flutter中,可以使用
StreamBuilder
来监听Stream。StreamBuilder
是一个Widget,它会根据Stream的状态和数据来构建UI。
StreamBuilder<DateTime>( stream: timeStream, builder: (BuildContext context, AsyncSnapshot<DateTime> snapshot) { if (snapshot.hasData) { // 这里snapshot.data就是最新的时间 return Text(snapshot.data.toString()); } else if (snapshot.hasError) { return Text('Error: ${snapshot.error}'); } return Text('Loading...'); }, )
- 在Flutter中,可以使用
- 在Widget中更新UI以显示实时时间:
- 当
StreamBuilder
监听到Stream有新数据时,builder
回调函数会被调用,从而触发UI的重建。 - 如上述代码,当
Stream
发出新的DateTime
对象时,snapshot.hasData
为true
,Text
组件会显示最新的时间,实现了UI的实时更新。
- 当
另外,也可以在StatefulWidget
的initState
方法中手动订阅Stream
,并在dispose
方法中取消订阅以避免内存泄漏。例如:
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late StreamSubscription<DateTime> _subscription;
DateTime? _currentTime;
@override
void initState() {
super.initState();
Stream<DateTime> timeStream = Stream.periodic(const Duration(seconds: 1), (count) => DateTime.now());
_subscription = timeStream.listen((data) {
setState(() {
_currentTime = data;
});
});
}
@override
void dispose() {
_subscription.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('实时时间'),
),
body: Center(
child: _currentTime == null? const Text('Loading...') : Text(_currentTime.toString()),
),
);
}
}
这种方式通过setState
来触发UI更新,从而显示实时时间。