Jus*_*ain 16 flutter inherited-widget flutter-provider
Provider 包使用InheritedWidget. 当我在对话框中时想访问提供程序时,这是一个问题。如果我使用加载对话框
showDialog(... builder: (context) => MyDialog);
Run Code Online (Sandbox Code Playgroud)
我无法访问任何东西,InheritedWidget因为我的对话框不是主小部件树的一部分。这也意味着我无法访问我的 Provider 提供商,对吗?
我的问题是:如果它不是主应用程序小部件树的一部分,我如何在对话框中访问我的提供程序?
final firebaseAuth = Provider.of<FirebaseAuth>(context);
Run Code Online (Sandbox Code Playgroud)
我在使用BLoCs. 如果我尝试在对话框中通过 检索它们InheritedWidget,它们将失败。我已经通过BLoC在构造函数中传递了来解决这个问题,但这似乎违背了InheritedWidgets.
您可以使用 BlocProvider.value,而不是在构造函数中传递 BLoC。
https://pub.dev/documentation/flutter_bloc/latest/flutter_bloc/BlocProvider/BlocProvider.value.html
这将允许您将现有的 BLoC 实例提供给新路由(对话框)。你仍然可以享受所有的好处InheritedWidget
// Get the BLoC using the provider
MyBloc myBloc = BlocProvider.of<MyBloc>(context);
showDialog(
context: context,
builder: (BuildContext context) {
Widget dialog = SimpleDialog(
children: <Widget>[
... // Now you can call BlocProvider.of<MyBloc>(context); and it will work
],
);
// Provide the existing BLoC instance to the new route (the dialog)
return BlocProvider<MyBloc>.value(
value: myBloc, //
child: dialog,
);
},
);
Run Code Online (Sandbox Code Playgroud)
.value() 也适用于 ChangeNotifierProvider、ListenableProvider 等。 https://pub.dev/documentation/provider/latest/provider/ChangeNotifierProvider/ChangeNotifierProvider.value.html
小智 5
我在这部分卡住了一段时间。老实说,我不想传递提供程序,当您处理复杂的小部件时,解压缩小部件代码以获取父上下文也很困难(而且这似乎不是最好的方法)。
这更有意义
handleFileViewerClicked(context) async {
var reportState = Provider.of<ReportState>(context, listen: false);
/**
*The dialog will live in a new context and requires a new provider to be created for the report state
* For more information read the Provider.Consumer documentation and showDialog function signature.
*/
showDialog(
context: context,
//Notice the use of ChangeNotifierProvider<ReportState>.value
builder: (_) => ChangeNotifierProvider<ReportState>.value(
value: reportState,
child: FileViewer(),
),
);
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您的孩子小部件是 FileViewer 可以使用
class FileViewer extends StatelessWidget {
.
.
Widget build(BuildContext context) {
//you can enable or disable listen if you logic require so
var reportState = Provider.of<ReportState>(context);
return Text('${reportState.files.length}');
}
}
Run Code Online (Sandbox Code Playgroud)
我能够通过将数据集传递到警报对话框中来访问提供程序数据。有趣的是,您必须在对话框中调用 setState() 才能看到对话框中的更改。
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
final provider = Provider.of<DataSet>(context);
return Scaffold(
body: Container(
child: RaisedButton(
child: Text('Show Dialog'),
onPressed: () {
showDialog(context: context,
builder: (context) {
return DialogContent(dataSet: provider);
});
},
),
),
);
}
}
class DialogContent extends StatefulWidget {
final DataSet dataSet;
const DialogContent({Key key, this.dataSet}) : super(key: key);
@override
_DialogContentState createState() => _DialogContentState();
}
class _DialogContentState extends State<DialogContent> {
@override
Widget build(BuildContext context) {
return AlertDialog(
title: Text('Dialog with data'),
content: Text('${widget.dataSet.pieceOfData}'),
actions: <Widget>[
FlatButton(
child: Text('Increase Data'),
onPressed: () {
setState(() {
widget.dataSet.increaseData();
});
},
),
],
);
}
}
class DataSet with ChangeNotifier {
int pieceOfData = 1;
increaseData() {
pieceOfData += 1;
notifyListeners();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9586 次 |
| 最近记录: |