A FutureBuilder is a widget in Flutter that builds itself based on the latest snapshot of interaction with a Future. It’s a convenient way to handle asynchronous data and update the UI accordingly.
Properties:
- future: The Future that the builder will interact with.
- builder: A callback function that builds the widget based on the snapshot of the Future.
How it works:
- The FutureBuilder widget is created with a Future and a builder callback.
- The FutureBuilder interacts with the Future and gets the latest snapshot.
- The builder callback is called with the snapshot, and it returns a widget based on the snapshot’s state.
- The FutureBuilder updates the UI with the widget returned by the builder callback.
Snapshot states:
- ConnectionState
.
none: The future has not been initialized. - ConnectionState
.
waiting: The future is waiting for the data. - ConnectionState
.
done: The future has completed with data. - ConnectionState
.
active: The future is active and has data.
Example:
Future<String> fetchData() async {
// Simulate a network request
await Future.delayed(Duration(seconds: 2));
return 'Data from future';
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: fetchData(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
} else if (snapshot.hasData) {
return Center(child: Text(snapshot.data!));
} else {
return Center(child: Text('Error'));
}
},
);
}
In this example, the FutureBuilder interacts with the fetchData future and builds a widget based on the snapshot’s state. If the future is waiting, it displays a CircularProgressIndicator. If the future has completed with data, it displays the data. If there’s an error, it displays an error message.
class FutureBuilderExample extends StatelessWidget {
// Simulate a network request or any asynchronous operation
Future<String> fetchData() async {
await Future.delayed(Duration(seconds: 2)); // Simulating network delay
// Return fetched data
return 'Data fetched from server!';
// Uncomment the line below to simulate an error
// throw Exception('Error fetching data!');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('FutureBuilder Example'),
),
body: Center(
child: FutureBuilder<String>(
future: fetchData(), // The future to work with
builder: (context, snapshot) {
// Check the connection state
if (snapshot.connectionState == ConnectionState.waiting) {
// While waiting for data, show a loading indicator
return CircularProgressIndicator();
} else if (snapshot.hasError) {
// If there was an error fetching data, show an error message
return Text('Error: ${snapshot.error}');
} else if (snapshot.hasData) {
// If data is fetched successfully, display it
return Text(
snapshot.data!,
style: TextStyle(fontSize: 18),
);
} else {
// Handle any other possible state
return Text('No data available');
}
},
),
),
);
}
}