在Flutter, FutureBuilder Widget 用于根据与 Future 交互的最新快照创建小部件。这是必要的要被通过的状态或变化的依赖关系的变化更早或者获得未来。 FutureBuilder是一个 Widget,它将帮助您执行一些异步函数,并根据该函数的结果您的 UI 将更新。
FutureBuilder本质上是有状态的,即它保持自己的状态,就像我们在StatefulWidgets 中所做的那样。
语法:
FutureBuilder(
Key key,
this.future,
this.initialData,
@required this.builder,
)
And, builder should not be null.
当我们使用FutureBuilder小部件时,我们需要检查未来状态,即未来是否已解决等等。有各种状态如下:
- ConnectionState.none :表示 future 为 null 并且initialData用作defaultValue 。
- ConnectionState.active :表示未来不为空,但尚未解决。
- ConnectionState.waiting :表示未来正在解决,我们很快就会得到结果。
- ConnectionState.done :表示未来已经解决。
我们将逐步创建FutureBuilder Widget。
第 1 步:创造一个需要解决的未来。
Dart
/// Function that will return a
/// "string" after some time
/// To demonstrate network call
/// delay of [2 seconds] is used
///
/// This function will behave as an
/// asynchronous function
Future getData() {
return Future.delayed(Duration(seconds: 2), () {
return "I am data";
// throw Exception("Custom Error");
});
}
Dart
FutureBuilder(
builder: (ctx, snapshot) {
... some code here
// Displaying LoadingSpinner to indicate waiting state
return Center(
child: CircularProgressIndicator(),
);
},
// Future that needs to be resolved
// inorder to display something on the Canvas
future: getData(),
),
Dart
FutureBuilder(
builder: (ctx, snapshot) {
// Checking if future is resolved
if (snapshot.connectionState == ConnectionState.done) {
// If we got an error
if (snapshot.hasError) {
return Center(
child: Text(
'${snapshot.error} occured',
style: TextStyle(fontSize: 18),
),
);
// if we got our data
} else if (snapshot.hasData) {
// Extracting data from snapshot object
final data = snapshot.data as String;
return Center(
child: Text(
'$data',
style: TextStyle(fontSize: 18),
),
);
}
}
... some code here
),
Dart
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'GeeksforGeeks',
// to hide debug banner
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 {
/// Function that will return a
/// "string" after some time
/// To demonstrate network call
/// delay of [2 seconds] is used
///
/// This function will behave as an
/// asynchronous function
Future getData() {
return Future.delayed(Duration(seconds: 2), () {
return "I am data";
// throw Exception("Custom Error");
});
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: Text('Future Demo Page'),
),
body: FutureBuilder(
builder: (ctx, snapshot) {
// Checking if future is resolved or not
if (snapshot.connectionState == ConnectionState.done) {
// If we got an error
if (snapshot.hasError) {
return Center(
child: Text(
'${snapshot.error} occured',
style: TextStyle(fontSize: 18),
),
);
// if we got our data
} else if (snapshot.hasData) {
// Extracting data from snapshot object
final data = snapshot.data as String;
return Center(
child: Text(
'$data',
style: TextStyle(fontSize: 18),
),
);
}
}
// Displaying LoadingSpinner to indicate waiting state
return Center(
child: CircularProgressIndicator(),
);
},
// Future that needs to be resolved
// inorder to display something on the Canvas
future: getData(),
),
),
);
}
}
上面的代码片段是为了演示一个真实的网络调用。我们使用了 2 秒的延迟。
第 2 步:创建FutureBuilder Widget 并管理等待状态。
Dart
FutureBuilder(
builder: (ctx, snapshot) {
... some code here
// Displaying LoadingSpinner to indicate waiting state
return Center(
child: CircularProgressIndicator(),
);
},
// Future that needs to be resolved
// inorder to display something on the Canvas
future: getData(),
),
在这个片段中,我们可以看到我们正在返回一个 LoadingSpinner。它只会在未来处于等待状态时显示。
第 3 步:管理 Future完成状态,即在解决 Future 时。此步骤还需要检查网络调用期间可能发生的任何错误。
Dart
FutureBuilder(
builder: (ctx, snapshot) {
// Checking if future is resolved
if (snapshot.connectionState == ConnectionState.done) {
// If we got an error
if (snapshot.hasError) {
return Center(
child: Text(
'${snapshot.error} occured',
style: TextStyle(fontSize: 18),
),
);
// if we got our data
} else if (snapshot.hasData) {
// Extracting data from snapshot object
final data = snapshot.data as String;
return Center(
child: Text(
'$data',
style: TextStyle(fontSize: 18),
),
);
}
}
... some code here
),
在上面的代码段中,您可以看到我们正在检查
snapshot.hasError
This step is require because it could be possible that future is resolved but an error has occured.
我们也在检查
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.
完整的源代码:
Dart
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'GeeksforGeeks',
// to hide debug banner
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 {
/// Function that will return a
/// "string" after some time
/// To demonstrate network call
/// delay of [2 seconds] is used
///
/// This function will behave as an
/// asynchronous function
Future getData() {
return Future.delayed(Duration(seconds: 2), () {
return "I am data";
// throw Exception("Custom Error");
});
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
appBar: AppBar(
title: Text('Future Demo Page'),
),
body: FutureBuilder(
builder: (ctx, snapshot) {
// Checking if future is resolved or not
if (snapshot.connectionState == ConnectionState.done) {
// If we got an error
if (snapshot.hasError) {
return Center(
child: Text(
'${snapshot.error} occured',
style: TextStyle(fontSize: 18),
),
);
// if we got our data
} else if (snapshot.hasData) {
// Extracting data from snapshot object
final data = snapshot.data as String;
return Center(
child: Text(
'$data',
style: TextStyle(fontSize: 18),
),
);
}
}
// Displaying LoadingSpinner to indicate waiting state
return Center(
child: CircularProgressIndicator(),
);
},
// Future that needs to be resolved
// inorder to display something on the Canvas
future: getData(),
),
),
);
}
}
输出:
想要一个更快节奏和更具竞争力的环境来学习 Android 的基础知识吗?
单击此处前往由我们的专家精心策划的指南,旨在让您立即做好行业准备!