[英]How to open new MaterialPageRoute as a child in widget tree in Flutter
In the example below when I push new MaterialPageRoute it is created on the same level as Home widget in the Flutter widget tree.在下面的示例中,当我推送新的 MaterialPageRoute 时,它与 Flutter 小部件树中的 Home 小部件在同一级别上创建。 I would like to have it as a child of widget Home, so Home would be a parent of Child widget.
我想将它作为小部件 Home 的子级,因此 Home 将是 Child 小部件的父级。
Here is a full code:这是一个完整的代码:
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
home: Home(),
));
}
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
Center(
child: Text("This is home"),
),
RaisedButton(
child: Text("Open child view"),
onPressed: () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => Child()));
},
)
],
),
);
}
}
class Child extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Text("Child view"),
));
}
}
Here is how the widget tree looks like这是小部件树的样子
I want to achieve that because I would like to initialize the ScopedModel in Home widget and have it available in every new MaterialPageRoute I create.我想实现这一点,因为我想在 Home 小部件中初始化 ScopedModel 并让它在我创建的每个新 MaterialPageRoute 中都可用。
I solved my issue using nested Navigator.我使用嵌套导航器解决了我的问题。
Here is the example:这是示例:
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
home: Home(),
));
}
var homeNavigatorKey = GlobalKey<NavigatorState>();
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Navigator(
key: homeNavigatorKey,
onGenerateRoute: (settings) {
/*dirty code for illustration purposes only*/
if (settings.name == '/child') {
return MaterialPageRoute(builder: (context) => Child());
} else {
return MaterialPageRoute(
builder: (context) => Column(
children: <Widget>[
Center(
child: Text("This is home"),
),
RaisedButton(
child: Text("Open child view"),
onPressed: () {
homeNavigatorKey.currentState.pushNamed('/child');
},
)
],
));
}
},
),
);
}
}
class Child extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: RaisedButton(
onPressed: () => Navigator.of(context).pop(),
child: Text("Back to home"),
),
));
}
}
The tree looks like this树长这样
and allows for passing data from Home to every child.并允许将数据从家庭传递给每个孩子。
Feel free to comment or post answers if you have any simpler solution.如果您有任何更简单的解决方案,请随时发表评论或发布答案。
Navigator.of(context).push()
will replace your Home
screen with a new screen (while keeping the Home
screen in memory so you can go back to it). Navigator.of(context).push()
将用新屏幕替换您的Home
屏幕(同时将Home
屏幕保留在 memory 中,以便您可以 go 回到它)。 They are on the same level in the widget tree, the only way to nest them is to use nested Navigators
I think.它们在小部件树中处于同一级别,我认为嵌套它们的唯一方法是使用嵌套的
Navigators
。
But, given what you want to achieve: why not initialize the ScopedModel one level up and provide at the root of your widget tree?但是,考虑到您想要实现的目标:为什么不将 ScopedModel 向上初始化一级并在小部件树的根部提供呢? That way you can access your model both in the
Home
screen as well as the Child
screen.这样您就可以在
Home
屏幕和Child
屏幕中访问您的 model。
Below is how you could do that, I added a simple ScopedModel and am able to access it's text
property inside the Child
screen.下面是如何做到这一点,我添加了一个简单的 ScopedModel 并且能够在
Child
屏幕中访问它的text
属性。
import 'package:flutter/material.dart';
import 'package:scoped_model/scoped_model.dart';
import 'package:tryout/model.dart';
void main() {
runApp(
ScopedModel<TestModel>(
model: TestModel(),
child: MaterialApp(
home: Home(),
),
)
);
}
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: <Widget>[
Center(
child: Text("This is home"),
),
RaisedButton(
child: Text("Open child view"),
onPressed: () {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => Child()));
},
)
],
),
);
}
}
class Child extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: Text("${ScopedModel.of<TestModel>(context).text}"),
));
}
}
And here's the TestModel
class:这是
TestModel
class:
import 'package:scoped_model/scoped_model.dart';
class TestModel extends Model {
String _text = "Test to see if this works!";
String get text => _text;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.