我希望FutureBuilder等待用户在路线或对话框(以下示例)中进行选择,然后将该数据返回给构建器。但是,对话框永远不会出现。
我如何等待使用FutureBuilder从屏幕或对话框返回数据?
import 'package:flutter/material.dart';
void main() => runApp(HomeScreen());
class HomeScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: FutureBuilder(
future: launch(context),
builder: (context, snapshot) {
// use result from screen or dialog in snapshot.data
return Center(child: Text(snapshot.data));
}),
),
);
}
Future launch(BuildContext context) async {
return await showDialog<void>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
actions: <Widget>[
FlatButton(
child: Text('Send Data'),
onPressed: () {
// return some data
Navigator.pop(context, 'Some data!');
},
),
],
content: Container(child: Text('')),
);
},
);
}
}
答案 0 :(得分:2)
您可以在下面复制粘贴运行完整代码
步骤1:您需要使用addPostFrameCallback
步骤2:将MaterialApp
移到上一级
步骤3:检查ConnectionState
代码段
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback((_) {
setState(() {
_future = launch(context);
});
});
super.initState();
}
Future<String> launch(BuildContext context) async {
var result = await showDialog(
...
print("result $result");
return Future.value(result);
}
工作演示dartpad link
完整代码
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: HomeScreen(),
);
}
}
class HomeScreen extends StatefulWidget {
@override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
Future<String> _future;
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback((_) {
setState(() {
_future = launch(context);
});
});
super.initState();
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
body: FutureBuilder(
future: _future,
builder: (context, AsyncSnapshot<String> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
return Text('none');
case ConnectionState.waiting:
return Center(child: CircularProgressIndicator());
case ConnectionState.active:
return Text('');
case ConnectionState.done:
if (snapshot.hasError) {
return Text(
'${snapshot.error}',
style: TextStyle(color: Colors.red),
);
} else {
return Center(child: Text("his this is ${snapshot.data}"));
}
}
}),
),
);
}
Future<String> launch(BuildContext context) async {
var result = await showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
actions: <Widget>[
FlatButton(
child: Text('Send Data'),
onPressed: () {
// return some data
Navigator.pop(context, 'Some data!');
},
),
],
content: Container(child: Text('')),
);
},
);
print("result $result");
return Future.value(result);
}
}
答案 1 :(得分:1)
感谢您使用将来的Completer进行还原,以从Dialogue中获取数据
创建一个Completer实例
var dialogueFuture = Completer();
将完成者的未来提供给Future builder
FutureBuilder{
future : dialogueFuture.future,
...
}
在显示对话功能中,像这样完成Future
var theData = await showDialogue(...)
dialogFuture.complete(theData);
请参阅飞镖here