Solución:
usar MaterialApp.onGenerateRoute
propiedad como esta:
onGenerateRoute: (RouteSettings settings) {
print('build route for ${settings.name}');
var routes = <String, WidgetBuilder>{
"hello": (ctx) => Hello(settings.arguments),
"other": (ctx) => SomeWidget(),
};
WidgetBuilder builder = routes[settings.name];
return MaterialPageRoute(builder: (ctx) => builder(ctx));
},
ahora puedes simplemente usar NavigatorState.pushNamed
:
Navigator.of(context).pushNamed("hello", arguments: "world");
aquí tienes alguna prueba Hello
widget:
class Hello extends StatelessWidget {
final String greet;
Hello(this.greet);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Text(
'hello $greet',
textScaleFactor: 5.0,
),
),
);
}
}
Acabo de tener el mismo problema que tú y puse una solución. En lugar de usar onGenerateRoute, aún puede usar pushNamed Navigator para pasar argumentos y aún puede acceder a los argumentos de ModalRoute en initState, y así es como:
1) Utilice un futuro en initState para obtener acceso al contexto.
- Puedes hacer esto con
Future.delayed(Duration.zero, () {} )
- Esto le da acceso al contexto y también puede hacer cosas como showDialog en initState usando esto porque puede acceder al contexto aquí fuera del método de compilación.
2) Extraiga los argumentos usando ModalRoute.of(context).settings.arguments
- En el futuro, extraiga los argumentos y guárdelos en una variable declarada, pero no inicializada, que creó antes de initState pero, obviamente, todavía en el objeto State.
- Una vez que tenga los argumentos, puede hacer lo que quiera con ellos, como pasar la variable a una función tal vez.
- Nota importante: debe usar la variable dentro del cuerpo de la función futura, de lo contrario, Flutter omitirá el futuro (como está programado para hacerlo) y completará lo que esté afuera primero, por lo que var aún devolverá nulo porque el futuro no lo ha hecho. resolvió darle a la var un valor todavía.
Todo junto se vería así:
var = args;
_yourFunction(args) async {
// whatever you want to do
}
@override
void initState() {
super.initState();
// future that allows us to access context. function is called inside the future
// otherwise it would be skipped and args would return null
Future.delayed(Duration.zero, () {
setState(() {
args = ModalRoute.of(context).settings.arguments;
});
print(args['id']);
_yourFunction(args);
});
}
En lugar de enviar argumentos a través de pushNamed, puede llamar a push con un nuevo PageRoute.
Suponga que su tipo de argumento se llama Argumento. Así es como se ven su widget con estado y sus clases de estado:
class YourStatefulWidget extends StatefulWidget {
final Argument argument;
YourStatefulWidget({
@required this.argument,
});
@override
State<StatefulWidget> createState() {
return YourStatefulWidgetState();
}
}
class YourStatefulWidgetState extends State<YourStatefulWidget> {
@override
initState() {
super.initState();
// Refer to your argument here by "widget.argument"
}
}
Así es como se llama push con un PageRoute:
Navigator.of(context).push(MaterialPageRoute(builder: (context) => YourStatefulWidget(argument: Argument())));