S.D.
S.D.

Reputation: 5867

How to pass widget constructor as a parameter for another widget to build

Is there a way to pass one widget as a parameter to another?

My code has something similar to this with two TextWidget of type BoldWidget and ItalicWidget:

abstract class TextWidget extends StatelessWidget {
  final String text;

  TextWidget({
    @required this.text,
  });
}

class BoldWidget extends TextWidget {
  @override
  Widget build(BuildContext context) {
    return Text(this.text, style: TextStyle(fontWeight: FontWeight.bold),);
  }
}

class ItalicWidget extends TextWidget {
  @override
  Widget build(BuildContext context) {
    return Text(this.text, style: TextStyle(fontStyle: FontStyle.italic),);
  }
}

At runtime, I want to pass in either TextWidget as an argument to another widget (TextDisplay) like this:

class TextDisplay extends StatelessWidget {
  final TextWidget widget;
  final String string;

  const TextDisplay({Key key, this.widget, this.string}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return widget(string);
  }
}

What doesn't work in the code above is widget(string), with error message "'widget' isn't a function".

How can I pass one widget as another argument so it can constructed by another class?

My actual code can't build the TextWidget before passing it to TextDisplay as TextDisplay needs to apply some of the arguments to the TextWidget.

Upvotes: 10

Views: 9568

Answers (1)

diegoveloper
diegoveloper

Reputation: 103421

You can use the CallBack pattern using typedef :

  typedef CustomCallBack = TextWidget Function(String value);

  class TextDisplay extends StatelessWidget {
    final CustomCallBack widget;
    final String string;

    const TextDisplay({Key key, this.widget, this.string}) : super(key: key);

    @override
    Widget build(BuildContext context) {
      return widget(string);
    }
  }

Upvotes: 19

Related Questions