我需要pass提供者(Model2)从homepage到Page2,所以当用户返回homepage (onWillPop)时,我可以从提供者(Model2)进行API调用并更新homepage。
但是,当我调用_onPaidBackPress(context)时,会出现错误:
未处理的异常:错误:无法找到此消费者Widget之上的正确提供程序
主页中的StatefulWidget:
@override
Widget build(BuildContext context) {
return ChangeNotifierProxyProvider<Model1, Model2>(
initialBuilder: (_) => Model2(),
builder: (_, model1, model2) => model2
..string = model1.string,
),
child: Consumer<Model2>(
builder: (context, model2, _) =>
...
await Navigator.push(
context,
new MaterialPageRoute(
builder: (BuildContext context) =>
new Page2(
context: context)));在Page2中:
class Page2 extends StatefulWidget {
final BuildContext context;
Page2({Key key, this.context}) : super(key: key);
@override
State createState() => new Page2State(context: context);
}
class Page2State extends State<Page2> {
final context;
ChatScreenState({Key key, this.context});
@override
Widget build(BuildContext context) {
return Consumer<Model1>(
builder: (context, model, _) {
return new WillPopScope(
onWillPop: () => model.isPaid ? _onPaidBackPress(context) : _onBackPressed(context),
Future<void> _onPaidBackPress(context) async {
final model2 = Provider.of<Model2>(context, listen: false);
return showDialog<void>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return
Provider.value(value: model2, child:
AlertDialog(
title: Text('Back'),
content: SingleChildScrollView(
child: ListBody(
children: <Widget>[
Text('Go back'),
],
),
),
actions: <Widget>[
FlatButton(
child: Text('OK'),
onPressed: () async {
await model2.getData();
Navigator.of(context).pop();
},
),
],
),
);
},
);
}谢谢你帮忙!
发布于 2020-09-01 14:35:57
在导航到新页时,可以通过创建新提供程序轻松地传递Navigator中的提供程序。
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) => Provider(
create: (context) => InventoryItem(),
builder: (context, child) => ProductDetails(),
),
),
);这里要么创建一个新的对象InventoryItem(),要么传递现有的提供程序对象。
发布于 2019-08-21 19:50:35
您需要使提供程序出现在Navigator Widget之上,才能成为当前Widget的锚。这意味着,它必须驻留在MaterialApp()、CupertinoApp()或您可能使用的任何Directionality()之上。
有关InheritedWidget的更多信息,请参考以下链接。
发布于 2020-08-05 17:18:34
我有点晚了,但我找到了一个解决方案,说明如何使Provider的值在Navigator.push()之后存活,而不必将Provider置于MaterialApp之上。
为此,我使用了库custom_navigator。它允许您在树中的任何地方创建Navigator。
您必须创建两种不同的GlobalKey<NavigatorState>,它们将提供给MaterialApp和CustomNavigator小部件。这些键将允许您控制您想要使用的导航器。
这里有一个小片段来说明如何做
class App extends StatelessWidget {
GlobalKey<NavigatorState> _mainNavigatorKey = GlobalKey<NavigatorState>(); // You need to create this key for the MaterialApp too
@override
Widget build(BuildContext context) {
return MaterialApp(
navigatorKey: _mainNavigatorKey; // Give the main key to the MaterialApp
home: Provider<bool>.value(
value: myProviderFunction(),
child: Home(),
),
);
}
}
class Home extends StatelessWidget {
GlobalKey<NavigatorState> _navigatorKey = GlobalKey<NavigatorState>(); // You need to create this key to control what navigator you want to use
@override
Widget build(BuildContext context) {
final bool myBool = Provider.of<bool>(context);
return CustomNavigator (
// CustomNavigator is from the library 'custom_navigator'
navigatorKey: _navigatorKey, // Give the second key to your CustomNavigator
pageRoute: PageRoutes.materialPageRoute,
home: Scaffold(
body: FlatButton(
child: Text('Push'),
onPressed: () {
_navigatorKey.currentState.push( // <- Where the magic happens
MaterialPageRoute(
builder: (context) => SecondHome(),
),
},
),
),
),
);
}
}
class SecondHome extends StatelessWidget {
@override
Widget build(BuildContext context) {
final bool myBool = Provider.of<bool>(context);
return Scaffold(
body: FlatButton(
child: Text('Pop'),
onPressed: () {
Novigator.pop(context);
},
),
);
}
}在这里,您可以从myBool小部件中的Provider读取值,但也可以读取SecondHome小部件,即使在Navigator.push()之后也是如此。
然而,Android back按钮将触发来自MaterialApp导航器的Navigator.pop()。如果您想使用CustomNavigator的一个,可以这样做:
// In the Home Widget insert this
...
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
if (_navigatorKey.currentState.canPop()) {
_navigatorKey.currentState.pop(); // Use the custom navigator when available
return false; // Don't pop the main navigator
} else {
return true; // There is nothing to pop in the custom navigator anymore, use the main one
}
},
child: CustomNavigator(...),
);
}
...https://stackoverflow.com/questions/57598029
复制相似问题