Home > Enterprise >  Pass either a widget or a callback to button
Pass either a widget or a callback to button

Time:10-19

I'm trying to make a custom ElevatedButton widget whose constructor will receive one of two options:

  1. either a new page to push into the Navigator (my custom StatefulWidget),
  2. or a callback method to override the button's onPressed entirely.

I tried to create two separate constructors - one for each of the possibilities but the constructor which is supposed to receive the callback method doesn't seem to get it. When I debug the code I see the received object is Closure.

What am I doing wrong?

import 'package:flutter/material.dart';

// ignore: must_be_immutable
class OrdinaryButton extends StatelessWidget {
  final String? text;
  Widget? goto;
  late Function()? onPressed;

  OrdinaryButton({this.text, this.goto});

  OrdinaryButton.overrideOnPressed({this.text, required this.onPressed})
  {
    this.goto = null;
  }

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
              child: Text("$text"),
              onPressed: () {
                if(goto != null)
                {
                  print("LOG: opening a new page...");
                  Navigator.push(context, MaterialPageRoute(builder: (context) => goto!));
                }
                else if(this.onPressed != null)
                {
                  print("LOG: calling a custom function...");
                  this.onPressed; // This has the 'Closure' object instead of my callback.
                }
              },
            );
  }
}

CodePudding user response:

you missed "!()"after "onPressed" your code works for me

hello() {
  print("hello");
}


//Call this widget in my code 

Column(
        children: [

          OrdinaryButton.overrideOnPressed(
            onPressed: hello,
            text: "Salut",
          )
        ],
      ),
 


class OrdinaryButton extends StatelessWidget {
  final String? text;
  Widget? goto;
  late Function()? onPressed;

  OrdinaryButton({Key? key, this.text, this.goto}) : super(key: key);

  OrdinaryButton.overrideOnPressed({this.text, required this.onPressed}) {
    goto = null;
  }

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      child: Text("$text"),
      onPressed: () {
        if (goto != null) {
          print("LOG: opening a new page...");
          Navigator.push(
              context, MaterialPageRoute(builder: (context) => goto!));
        } else if (onPressed != null) {
          print("LOG: calling a custom function...");
          onPressed!();
    //you missed "!()" here after onPressed 
        }
      },
    );
  }
}

  • Related