In Flutter, the FutureBuilder Widget is used to create widgets based on the latest snapshot of interaction with a Future. It is necessary for Future to be obtained earlier either through a change of state or change in dependencies. FutureBuilder is a Widget that will help you to execute some asynchronous function and based on that function’s result your UI will update.
FutureBuilder is Stateful by nature i.e it maintains its own state as we do in StatefulWidgets.
Syntax:
FutureBuilder(
Key key,
this.future,
this.initialData,
@required this.builder,
)
And, builder should not be null.
When we use the FutureBuilder widget we need to check for future state i.e future is resolved or not and so on. There is various State as follows:
- ConnectionState.none: It means that the future is null and initialData is used as defaultValue.
- ConnectionState.active: It means the future is not null but it is not resolved yet.
- ConnectionState.waiting: It means the future is being resolved, and we will get the result soon enough.
- ConnectionState.done: It means that the future has been resolved.
We will create FutureBuilder Widget in a step by step manner.
Step 1: Create a future that needs to be resolved.
Dart
Future<String> getData() {
return Future.delayed(Duration(seconds: 2), () {
return "I am data" ;
});
}
|
The above snippet is to demonstrate a real network call. We have used a 2 seconds delay.
Step 2: Create a FutureBuilder Widget and manage the waiting state.
Dart
FutureBuilder(
builder: (ctx, snapshot) {
... some code here
return Center(
child: CircularProgressIndicator(),
);
},
future: getData(),
),
|
In this snippet, we can see we are returning a LoadingSpinner. It will only be displayed when the future is in the Waiting state.
Step 3: Manage Future done state i.e when the future is resolved. This step also requires checking for any error that could occur during a network call.
Dart
FutureBuilder(
builder: (ctx, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return Center(
child: Text(
'${snapshot.error} occurred' ,
style: TextStyle(fontSize: 18),
),
);
} else if (snapshot.hasData) {
final data = snapshot.data as String;
return Center(
child: Text(
'$data' ,
style: TextStyle(fontSize: 18),
),
);
}
}
... some code here
),
|
In the above snippet, you can see we are checking
snapshot.hasError
This step is require because it could be possible that future is resolved but an error has occurred.
We are also checking
snapshot.hasData
This step is required because it may be possible that future is resolved but nothing is returned
due to some reasons, so always perform these checks otherwise you may get unexpected behaviour.
Complete Source Code:
Dart
import 'package:flutter/material.dart' ;
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'GeeksforGeeks' ,
debugShowCheckedModeBanner: false ,
theme: ThemeData(
primarySwatch: Colors.green,
),
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: Text( 'GeeksforGeeks' ),
),
body: Center(
child: ElevatedButton(
onPressed: () => Navigator.push(
context,
MaterialPageRoute(
builder: (ctx) => FutureDemoPage(),
),
),
child: Text( 'Demonstrate FutureBuilder' ),
),
),
),
);
}
}
class FutureDemoPage extends StatelessWidget {
Future<String> getData() {
return Future.delayed(Duration(seconds: 2), () {
return "I am data" ;
});
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: Text( 'Future Demo Page' ),
),
body: FutureBuilder(
builder: (ctx, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return Center(
child: Text(
'${snapshot.error} occurred' ,
style: TextStyle(fontSize: 18),
),
);
} else if (snapshot.hasData) {
final data = snapshot.data as String;
return Center(
child: Text(
'$data' ,
style: TextStyle(fontSize: 18),
),
);
}
}
return Center(
child: CircularProgressIndicator(),
);
},
future: getData(),
),
),
);
}
}
|
Output:
Whether you're preparing for your first job interview or aiming to upskill in this ever-evolving tech landscape,
GeeksforGeeks Courses are your key to success. We provide top-quality content at affordable prices, all geared towards accelerating your growth in a time-bound manner. Join the millions we've already empowered, and we're here to do the same for you. Don't miss out -
check it out now!
Last Updated :
07 Jun, 2022
Like Article
Save Article