Reputation: 9859
I have got StreamBuilder
. I am trying to do progress indicator with it. Like:
Loading token DONE
Loading regions DONE
Loading industry DONE
After the last item ("Loading industry DONE") and before switching to HomePage
I would like to add small delay. But I can't understand how to do it. I tried to use Future.delayed
and Timer
, but with them switching to HomePage do not happen. Without Delay/Timer switching works, but I need delay before it.
Here is my code:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/semantics.dart';
import 'package:provider/provider.dart';
import 'main.dart';
class SplashScreen extends StatefulWidget {
SplashScreenState createState() => SplashScreenState();
}
class SplashScreenState extends State<SplashScreen> {
String tokenLoadingState = '';
String regionsLoadingState = '';
String industryLoadingState = '';
TenderApiProvider apiProv;
@override
Widget build(BuildContext context) {
apiProv = Provider.of<TenderApiProvider>(context);
return StreamBuilder(
stream: apiProv.resultController,
builder: (BuildContext context, AsyncSnapshot snapshot) {
TenderApiProvider apiProv = Provider.of<TenderApiProvider>(context);
if (snapshot.data is ApiKeyLoadingState) {
switch (snapshot.data) {
case ApiKeyLoadingState.Progress:
tokenLoadingState = "Loading";
break;
case ApiKeyLoadingState.Done:
tokenLoadingState = "Done";
break;
case ApiKeyLoadingState.Error:
tokenLoadingState = "Error";
break;
default:
return Text("Unknown");
}
} else if (snapshot.data is RegionsLoadingState) {
switch (snapshot.data) {
case RegionsLoadingState.Progress:
regionsLoadingState = "Loading";
break;
case RegionsLoadingState.Done:
regionsLoadingState = "Done";
break;
case RegionsLoadingState.Error:
regionsLoadingState = "Error";
break;
default:
return Text("Unknown");
}
} else if (snapshot.data is IndustryLoadingState) {
switch (snapshot.data) {
case IndustryLoadingState.Progress:
industryLoadingState = "Loading";
break;
case IndustryLoadingState.Done:
industryLoadingState = "Done";
break;
case IndustryLoadingState.Error:
industryLoadingState = "Error";
break;
default:
return Text("Unknown");
}
if (apiProv.apiKeyLoadingState == ApiKeyLoadingState.Done &&
apiProv.regionsLoadingState == RegionsLoadingState.Done &&
apiProv.industryLoadingState == IndustryLoadingState.Done) {
Future.delayed(Duration(milliseconds: 1000)).then(
(_) => HomePage() // I need delay before switching to HomePage
);
}
}
return Scaffold(
appBar: AppBar(),
body: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
"Loading token: $tokenLoadingState",
textScaleFactor: 2,
),
Text(
"Loading regions: $regionsLoadingState",
textScaleFactor: 2,
),
Text(
"Loading industry: $industryLoadingState",
textScaleFactor: 2,
),
],
)));
});
}
}
Upvotes: 0
Views: 3327
Reputation: 1424
You need to move you logic outside of the build method. The build method in flutter must not have a delay, else your UI would lag very heavy.
For your usecase, StreamBuilder might not fit. It fits for dynamically displaying content depending of the state of your stream. It tho is not suitable for Routing or Navigation, as this would break the build process of the widget. That means, you have to manually subscribe to the stream. Here is an example. I cant test it, because you have many hidden dependencies.
@override
void initState() {
super.initState();
SchedulerBinding.instance.addPostFrameCallback((_) {
TenderApiProvider apiProv = Provider.of<TenderApiProvider>(context);
apiProv.resultController.listen((data) async {
if (apiProv.apiKeyLoadingState == ApiKeyLoadingState.Done &&
apiProv.regionsLoadingState == RegionsLoadingState.Done &&
apiProv.industryLoadingState == IndustryLoadingState.Done) {
await Future.delayed(Duration(milliseconds: 1000));// I need delay before switching to HomePag
Navigator.of(context).pushNamed('/home');
}
});
});
}
As I can sense you are fairly new to flutter, please consider taking one of the existing free video courses available on youtube.
Upvotes: 2
Reputation: 4260
Try:
import 'dart:async';
Timer(const Duration(milliseconds: 1000), () => HomePage());
Upvotes: 0