How to open new MaterialPageRoute as a child in widget tree in Flutter
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). They are on the same level in the widget tree, the only way to nest them is to use nested Navigators
I think.
But, given what you want to achieve: why not initialize the ScopedModel one level up and provide at the root of your widget tree? That way you can access your model both in the Home
screen as well as the Child
screen.
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.
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:
import 'package:scoped_model/scoped_model.dart';
class TestModel extends Model {
String _text = "Test to see if this works!";
String get text => _text;
}
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.