I was trying to pass argument to a button widget but I'm getting below error message.
Here is my argument:
ElevatedRegisterButton(
navigator: Navigator.of(context)
.push(MaterialPageRoute(builder: (context) {
return const RegisterPage1();
})))
Here is my widget where I was trying to pass argument:
import 'package:flutter/material.dart';
class ElevatedRegisterButton extends StatefulWidget {
const ElevatedRegisterButton({super.key, required this.navigator});
final String navigator;
@override
State<ElevatedRegisterButton> createState() => _ElevatedRegisterButtonState();
}
class _ElevatedRegisterButtonState extends State<ElevatedRegisterButton> {
@override
Widget build(BuildContext context) {
return ElevatedButton(
style: ElevatedButton.styleFrom(backgroundColor: Colors.red),
onPressed: () {
widget.navigator;
},
child: const Text('Register'),
);
}
}
Here is the error message I'm getting:
The argument type 'Future' can't be assigned to the parameter type 'String'.
CodePudding user response:
You need to set the navigator member to type final void Function(), because the onPressed property of ElevatedButton requires this type. You also need to pass it differently, because push is another type of function. Lastly, simply set onPressed to widget.navigator.
An example code is below based on your code snippet:
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) =>
const MaterialApp(home: Scaffold(body: HomePage()));
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) => SafeArea(
// see the difference, push is within () {}
child: ElevatedRegisterButton(navigator: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => const RegisterPage1()));
}),
);
}
class ElevatedRegisterButton extends StatefulWidget {
const ElevatedRegisterButton({super.key, required this.navigator});
final void Function() navigator;
@override
State<ElevatedRegisterButton> createState() => _ElevatedRegisterButtonState();
}
class _ElevatedRegisterButtonState extends State<ElevatedRegisterButton> {
@override
Widget build(BuildContext context) => ElevatedButton(
style: ElevatedButton.styleFrom(backgroundColor: Colors.red),
// here simply set the function
onPressed: widget.navigator,
child: const Text('Register'),
);
}
// added for demo purposes
class RegisterPage1 extends StatelessWidget {
const RegisterPage1({super.key});
@override
Widget build(BuildContext context) =>
const Scaffold(body: SafeArea(child: Text('RegisterPage1')));
}
CodePudding user response:
Problem 1
In your code:
class ElevatedRegisterButton extends StatefulWidget {
const ElevatedRegisterButton({super.key, required this.navigator});
// this line
final String navigator;
you are accepting a String navigator; but you are passing to it a Future:
ElevatedRegisterButton(
navigator: Navigator.of(context)
.push(MaterialPageRoute(builder: (context) {
return const RegisterPage1();
})))
problem 2
If you try running your code, you'll get an error:
setState() or markNeedsBuild called during build
So, to fix the issues, refactor your code as follows:
import 'package:flutter/material.dart';
const Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MaterialApp(home: MyApp()));
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.light().copyWith(),
debugShowCheckedModeBanner: false,
home: SafeArea(
child: Scaffold(
body: ElevatedRegisterButton(navigator: Navigator.of(context))),
),
);
}
}
class ElevatedRegisterButton extends StatefulWidget {
const ElevatedRegisterButton({super.key, required this.navigator});
final NavigatorState navigator;
@override
State<ElevatedRegisterButton> createState() => _ElevatedRegisterButtonState();
}
class _ElevatedRegisterButtonState extends State<ElevatedRegisterButton> {
@override
Widget build(BuildContext context) {
return ElevatedButton(
style: ElevatedButton.styleFrom(backgroundColor: Colors.red),
onPressed: () {
WidgetsBinding.instance.addPostFrameCallback((_) {
widget.navigator.push(MaterialPageRoute(
builder: (context) => Text("h1"),
));
});
},
child: const Text('Register'),
);
}
}
