Home > Enterprise >  Flutter Argument passing
Flutter Argument passing

Time:01-05

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'),
    );
  }
}

See also

setState() or markNeedsBuild called during build

  • Related