2

So I am trying to create a custom widget I can use in my flutter app. When creating this widget I want to always select a color (hence the required value) but I want to keep the cardChild and onpres values optional. How do I do this? I tried to give a empty Container and empty function as default values but then I get the errror

error: The default value of an optional parameter must be constant. (non_constant_default_value at [untitled1] lib/Components/reusable_card.dart:6)

here is my widget constructor:

class ReusableCard extends StatelessWidget {ReusableCard(
{required this.colour, this.cardChild = Container(), this.onPress = () {}});

  final Color colour;
  final Widget cardChild;
  final Function onPress;

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () {
        onPress;
      },
      child: Container(
        child: cardChild,
        margin: EdgeInsets.all(15.0),
        decoration: BoxDecoration(
          borderRadius: BorderRadius.all(Radius.circular(15.0)),
          color: colour,
        ),
      ),
    );
  }
}
Mark Wekking
  • 391
  • 1
  • 5
  • 14
  • 1
    either assign a `const` default values or allow `null`s - like: `final Widget? cardChild;` - for more info see how `Container` deals with optional [child](https://github.com/flutter/flutter/blob/77d935af4d/packages/flutter/lib/src/widgets/container.dart#L293) – pskink Jan 18 '22 at 10:54
  • Ahh the allowing for Nulls is exactly what I was looking for! – Mark Wekking Jan 18 '22 at 10:56

2 Answers2

5

you can use following approach

    class ReusableCard extends StatelessWidget {ReusableCard(
        {required this.colour, this.cardChild, this.onPress});
    
    final Color colour;
    final Widget? cardChild;
    final Function? onPress;
    
    @override
    Widget build(BuildContext context) {
      return GestureDetector(
        onTap: () {
          if(onPress != null){
            onPress!();
          }
        },
        child: Container(
          child: cardChild ?? Container(),
          margin: EdgeInsets.all(15.0),
          decoration: BoxDecoration(
            borderRadius: BorderRadius.all(Radius.circular(15.0)),
            color: colour,
          ),
        ),
      );
    }
  }
Hamza Siddiqui
  • 675
  • 5
  • 12
1

You can do it either by making cardChild and onPress positional parameter in the constructor.

class ReusableCard extends StatelessWidget {

  //constructor
  ReusableCard(this.colour,this.cardChild, this.onPress);

  final Color colour;
  final Widget cardChild;
  final Function onPress;

  @override
  Widget build(BuildContext context) {
  ....
  

or make them nullable by adding ?:

  class ReusableCard extends StatelessWidget {

  //constructor
  ReusableCard({required this.colour, this.cardChild, this.onPress});

  final Color colour;
  final Widget? cardChild;
  final Function? onPress;

  @override
  Widget build(BuildContext context) {
  ....

For better understanding about named and positional parameters read this.

Muhammad Hussain
  • 966
  • 4
  • 15