Building an app with Flutter and Riverpod, using a lot of:
ref.watch(someProvider).when(data: (someData){
// render layout with data
}, error: (err, stack) {
// do stuff with error
}, loading: (){
return LoadingScreen(); <----
})
The problem is that in most cases the loading screen only renders for a split second, causing a bad experience where the app feels a little "jumpy". I would like to be able to set a minimum of say 2 seconds for the loading state, is it possible to force a widget to stay rendered for a minimum amount of time some how?
CodePudding user response:
I have 2 suggestions for you :
Option A - You can put a delay of say 2 seconds in your provider, somewhere between loading and the next state. This way you make the loading screen visible at least 2 seconds.
Option B - You can also make a loadingScreen as an overlay Widget, which dismisses itself after say 2 seconds. This way you make the loading screen visible exactly 2 seconds.
I believe either way is fine in your case, since you say it flashes, I assume no heavy/long tasks are done in between states. In case you do need heavy/long tasks, option A guarantees the tasks are finished before loading screen disappears.
CodePudding user response:
You can create Stopwatch
to track (approximate) operation duration. This example will give you some idea.
final someProvider = FutureProvider<int>((ref) async {
final operationDuration = Duration(seconds: 1); //random, you can give it random to test
final stopwatch = Stopwatch()..start();
final data = await Future.delayed(operationDuration);
final minOperationTime = const Duration(seconds: 2);
final extraWaiting = minOperationTime.inMilliseconds - stopwatch.elapsed.inMilliseconds;
if (stopwatch.elapsed.inSeconds < 2) {
await Future.delayed(minOperationTime - stopwatch.elapsed);
}
return extraWaiting;
});
And widget
class LoadingTestOnFutureBuilder extends ConsumerWidget {
const LoadingTestOnFutureBuilder({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
return ref.watch(someProvider).when(data: (someData) {
return Text("got data ${someData}");
}, error: (err, stack) {
return Text("Err");
}, loading: () {
return CircularProgressIndicator();
});
}
}