This is the widget to work with Future objects.
If you need to build a widget that should consume a Future object – FutureBuilder is a good choice.
Constructor:
const FutureBuilder<T>( {Key? key, Future<T>? future, T? initialData, required AsyncWidgetBuilder<T> builder} )
Let’s try a simple example.
First, we going to add a method that returns a future response with some delay.
For the delay, we will use Future.delayed(const Duration(seconds: 5))
method.
Future<String> futureMethod() async { double random = Random().nextDouble(); String response = "Future text response"; await Future.delayed(const Duration(seconds: 5)); return Future(() => response); }
Inside initState
we call this method.
void initState() { super.initState(); _myData = futureMethod(); }
OK, we can add FutureBuilder now.
FutureBuilder<dynamic>( future: _myData, builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) { List<Widget> children; if (snapshot.hasData) { String data = snapshot.data; children = <Widget>[ const Icon( Icons.check_circle_outline, color: Colors.green, size: 60, ), Padding( padding: const EdgeInsets.only(top: 16), child: Text('Result: $data'), ), ]; } else if (snapshot.hasError) { children = <Widget>[ const Icon( Icons.error_outline, color: Colors.red, size: 60, ), Padding( padding: const EdgeInsets.only(top: 16), child: Text('Error: ${snapshot.error}'), ), ]; } else { children = const <Widget>[ SizedBox( width: 60, height: 60, child: CircularProgressIndicator(), ), Padding( padding: EdgeInsets.only(top: 16), child: Text('Awaiting result...'), ), ]; } return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: children), ); }, )
All done.
main.dart
import 'dart:math'; import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Future Builder', theme: ThemeData( primarySwatch: Colors.blue, ), home: const MyHomePage(title: 'FutureBuilder Home Page'), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({super.key, required this.title}); final String title; @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { Future<String>? _myData; Future<String> futureMethod() async { double random = Random().nextDouble(); String response = "Future text response"; await Future.delayed(const Duration(seconds: 5)); return Future(() => response); } @override void initState() { super.initState(); _myData = futureMethod(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Center( child: FutureBuilder<dynamic>( future: _myData, builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) { List<Widget> children; if (snapshot.hasData) { String data = snapshot.data; children = <Widget>[ const Icon( Icons.check_circle_outline, color: Colors.green, size: 60, ), Padding( padding: const EdgeInsets.only(top: 16), child: Text('Result: $data'), ), ]; } else if (snapshot.hasError) { children = <Widget>[ const Icon( Icons.error_outline, color: Colors.red, size: 60, ), Padding( padding: const EdgeInsets.only(top: 16), child: Text('Error: ${snapshot.error}'), ), ]; } else { children = const <Widget>[ SizedBox( width: 60, height: 60, child: CircularProgressIndicator(), ), Padding( padding: EdgeInsets.only(top: 16), child: Text('Awaiting result...'), ), ]; } return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: children), ); }, ), ), ); } }