我需要从Model2
到homepage
的传递提供者(Page2
),因此当用户返回homepage
(onWillPop
)时,我可以从提供者(Model2
)并更新homepage
。
但是当我打电话给_onPaidBackPress(context)
时出现错误:
未处理的异常:错误:找不到正确的 消费者微件上方的提供商
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)));
在第2页中:
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();
},
),
],
),
);
},
);
}
感谢帮助!
答案 0 :(得分:2)
导航到新页面时,可以通过创建新的提供程序来轻松地在Navigator中传递提供程序。
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) => Provider(
create: (context) => InventoryItem(),
builder: (context, child) => ProductDetails(),
),
),
);
在这里创建新对象InventoryItem()
或传递现有的提供者对象。
答案 1 :(得分:1)
我来晚了一些,但是我找到了一种解决方法,该解决方案是如何在Provider
之后保持Navigator.push()
的值,而不必将Provider
放在{{1}上方}。
为此,我使用了库custom_navigator
。它使您可以在树中的任意位置创建一个MaterialApp
。
您将必须创建两个分别用于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
,甚至在Home
之后也可以使用SecondHome
小部件。
但是,Android Navigator.push()
按钮将从back
的导航器中触发Navigator.pop()
。如果要使用MaterialApp
的密码,可以执行以下操作:
CustomNavigator
答案 2 :(得分:0)
您需要使Provider出现在Navigator Widget上方,以作为当前Widget的固定对象。也就是说,它必须位于MaterialApp()
,CupertinoApp()
或您可能使用的任何Directionality()
之上。
请参阅以下链接,以获取有关InheritedWidget的更多信息。
https://medium.com/@mehmetf_71205/inheriting-widgets-b7ac56dbbeb1