Last active
March 24, 2022 21:06
-
-
Save Andrious/45baa18a8620ded815da91989d3cff50 to your computer and use it in GitHub Desktop.
A mixin to supply a 'built-in' FutureBuilder Widget to a State object or any object.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// | |
/// Supply a FutureBuilder to a State object. | |
/// | |
import 'package:flutter/cupertino.dart'; | |
import 'package:flutter/material.dart'; | |
/// Replace 'dart:io' for Web applications | |
import 'package:universal_platform/universal_platform.dart'; | |
/// | |
mixin FutureBuilderStateMixin<T extends StatefulWidget> on State<T> { | |
/// Implement this function instead of the build() function | |
/// to utilize a built-in FutureBuilder Widget. | |
Widget buildWidget(BuildContext context) => const SizedBox(); | |
/// Run the CircularProgressIndicator() until asynchronous operations are | |
/// completed before the app proceeds. | |
@override | |
Widget build(BuildContext context) => FutureBuilder<bool>( | |
future: initAsync(), initialData: false, builder: futureBuilderBuilder); | |
/// Used to complete asynchronous operations | |
Future<bool> initAsync() async => true; | |
/// | |
Widget futureBuilderBuilder( | |
BuildContext context, AsyncSnapshot<bool> snapshot) { | |
// | |
Widget? widget; | |
FlutterErrorDetails? errorDetails; | |
if (snapshot.hasData && snapshot.data!) { | |
// Pass in the StatefulElement | |
widget = buildWidget(this.context); | |
// | |
} else if (snapshot.connectionState == ConnectionState.done) { | |
// | |
if (snapshot.hasError) { | |
// | |
final dynamic exception = snapshot.error; | |
errorDetails = FlutterErrorDetails( | |
exception: exception, | |
stack: exception is Error ? exception.stackTrace : null, | |
library: 'futurebuild_mixin.dart', | |
context: ErrorDescription('While getting ready in FutureBuilder'), | |
); | |
// Possibly recover resources and close services before continuing to exit in error. | |
onAsyncError(errorDetails); | |
// | |
} else { | |
// | |
errorDetails = FlutterErrorDetails( | |
exception: Exception('App failed to initialize'), | |
library: 'futurebuild_mixin.dart', | |
context: ErrorDescription('Please, notify Admin.'), | |
); | |
} | |
} | |
// A Widget must be supplied. | |
if (widget == null) { | |
// Keep trying until there's an error. | |
if (errorDetails == null) { | |
// | |
if (UniversalPlatform.isAndroid || UniversalPlatform.isWeb) { | |
// | |
widget = const Center(child: CircularProgressIndicator()); | |
} else { | |
// | |
widget = const Center(child: CupertinoActivityIndicator()); | |
} | |
// There was an error instead. | |
} else { | |
// | |
FlutterError.reportError(errorDetails); | |
widget = ErrorWidget.builder(errorDetails); | |
} | |
} | |
return widget; | |
} | |
/// Supply an 'error handler' routine if something goes wrong | |
/// in the corresponding initAsync() routine. | |
bool onAsyncError(FlutterErrorDetails details) => false; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment