Reputation: 658
I've been investigating the use of streams as I think this will the best solution for my app. I want to be able to check the time at specific intervals, then change the theme of a map automatically depending on whether the sun has risen or set. I have the themes and I have the sun code, but I need to join them together.
This is my code so far. If I use a double for the controller and subscription and simply generate a random number, then all is well. I get a different randomly generated number every second.
However, using the code below simply shows the same time over again.
Can somebody point me in the right direction with this?
import 'dart:async';
import 'dart:core';
import 'package:flutter/material.dart';
void main() => runApp(StreamTest());
class StreamTest extends StatefulWidget {
@override
_StreamTestState createState() => _StreamTestState();
}
class _StreamTestState extends State<StreamTest> {
StreamController<DateTime> controller =
StreamController<DateTime>.broadcast();
StreamSubscription<DateTime> streamSubscription;
DateTime currentTime = DateTime.now();
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Stream Demo",
home: Scaffold(
body: Center(
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
MaterialButton(
color: Colors.yellow,
child: Text("Subscribe"),
onPressed: () async {
getTime().listen((value) {
print('CURRENT TIME $currentTime');
});
},
),
MaterialButton(
child: Text('Unsubscribe'),
color: Colors.red[200],
onPressed: () {
streamSubscription.cancel();
},
),
],
),
),
),
);
}
}
Stream<DateTime> getTime() async* {
DateTime currentTime = DateTime.now();
while (true) {
await Future.delayed(Duration(seconds: 1));
yield currentTime;
}
}
thanks
Upvotes: 3
Views: 13147
Reputation: 558
as @pskink mentioned you can use Stream.periodic.
DateTime current = DateTime.now();
Stream timer = Stream.periodic( Duration(seconds: 1), (i){
current = current.add(Duration(seconds: 1));
return current;
});
timer.listen((data)=> print(data));
Upvotes: 6
Reputation: 9923
Inside your while (true) loop you're yielding the same variable you've set before. If you change it to yield DateTime.now()
it will generate new values each iteration.
Also change variable inside print call to value: print('CURRENT TIME $value');
.
To cancel the subscription later, store the value returned by listen method:
streamSubscription = getTime().listen((value) {
Result:
I/flutter ( 5716): CURRENT TIME 2019-11-14 13:50:34.318898
I/flutter ( 5716): CURRENT TIME 2019-11-14 13:50:35.323906
I/flutter ( 5716): CURRENT TIME 2019-11-14 13:50:36.328085
I/flutter ( 5716): CURRENT TIME 2019-11-14 13:50:37.332919
Upvotes: 2